Linux内核之原子操作:atomic_long_dec用法实例(六十七)

2024-05-03 02:20

本文主要是介绍Linux内核之原子操作:atomic_long_dec用法实例(六十七),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列原创干货持续更新中……】🚀
优质视频课程:AAOS车载系统+AOSP14系统攻城狮入门实战课原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

🍉🍉🍉文章目录🍉🍉🍉

    • 🌻1.前言
    • 🌻2.Linux内核之atomic_long_dec介绍
    • 🌻3.代码实例
      • 🐓3.1 资源计数
      • 🐓3.2 状态切换
      • 🐓3.3 同步机制
      • 🐓3.4 资源管理

🌻1.前言

本篇目的:Linux内核之原子操作:atomic_long_dec用法实例

🌻2.Linux内核之atomic_long_dec介绍

  • atomic_long_dec() 函数是 Linux 内核中用于对长整型(long)原子操作的函数之一。它的作用是以原子方式减少一个长整型变量的值,并且保证这个操作是不可中断的,即在多线程环境下也能保证数据的一致性和正确性。

  • 在 Linux 内核中,原子操作是一种特殊的操作,能够保证在多处理器或者多核系统上的并发执行过程中,对共享数据的访问是安全的,不会发生竞态条件(Race Condition)或者数据不一致的情况。atomic_long_dec() 函数正是通过这种机制来实现对长整型变量的安全减少。

  • 具体来说,atomic_long_dec() 函数接受一个指向 atomic_long_t 类型的变量的指针作为参数,然后将该变量的值减少 1,并且保证这个减少操作是原子的。在执行减少操作期间,如果其他线程尝试对同一个变量进行操作,它们会被阻塞,直到当前操作完成,从而确保了操作的完整性和一致性。

  • 这个函数在 Linux 内核中的应用非常广泛,特别是在实现并发数据结构、同步机制和各种驱动程序中。通过使用原子操作,开发人员可以编写出更加高效、稳定和可靠的多线程代码,而无需担心因为竞态条件而引发的各种问题。

  • atomic_long_dec() 函数是 Linux 内核中重要的原子操作函数之一,它的作用是实现对长整型变量的原子减少操作,确保多线程环境下的数据访问安全和一致性。

🌻3.代码实例

🐓3.1 资源计数

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/atomic.h>// 定义一个原子长整型变量,用于表示可用资源的数量
static atomic_long_t resource_count = ATOMIC_LONG_INIT(10); // 假设初始资源数量为10static int __init resource_manager_init(void) {// 模拟使用一个资源时,将资源数量减少1atomic_long_dec(&resource_count);printk(KERN_INFO "Resource used, remaining count: %ld\n", atomic_long_read(&resource_count));return 0;
}static void __exit resource_manager_exit(void) {printk(KERN_INFO "Exiting...\n");
}module_init(resource_manager_init);
module_exit(resource_manager_exit);MODULE_LICENSE("GPL");
  • 使用 atomic_long_dec() 函数来实现资源计数的功能。
  • 每次模块初始化时,模拟使用一个资源并将资源数量减少1,然后打印剩余资源数量。

🐓3.2 状态切换

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/atomic.h>// 定义一个表示状态的枚举类型
enum device_state {DEVICE_STATE_ACTIVE,DEVICE_STATE_IDLE,DEVICE_STATE_OFFLINE
};// 原子计数器数组,用于统计各个状态的设备数量
static atomic_long_t device_state_counts[] = {ATOMIC_LONG_INIT(0), // ACTIVEATOMIC_LONG_INIT(0), // IDLEATOMIC_LONG_INIT(0)  // OFFLINE
};static int __init device_status_init(void) {// 假设设备状态切换为 IDLE,将对应状态计数器减少1enum device_state current_state = DEVICE_STATE_IDLE;atomic_long_dec(&device_state_counts[current_state]);printk(KERN_INFO "Device status changed to IDLE, count: %ld\n", atomic_long_read(&device_state_counts[current_state]));return 0;
}static void __exit device_status_exit(void) {printk(KERN_INFO "Exiting...\n");
}module_init(device_status_init);
module_exit(device_status_exit);MODULE_LICENSE("GPL");
  • 使用 atomic_long_dec() 函数来实现设备状态的切换功能。
  • 每次模块初始化时,假设设备状态切换为 IDLE,然后将对应状态计数器减少1,并打印变更后的状态计数。

🐓3.3 同步机制

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/atomic.h>
#include <linux/delay.h>
#include <linux/kthread.h>// 全局的原子长整型变量,用于线程间同步
static atomic_long_t shared_variable = ATOMIC_LONG_INIT(10); // 假设初始值为10// 线程函数,每秒减少一次共享变量的值
static int my_thread_func(void *data) {int i;for (i = 0; i < 5; ++i) {msleep(1000);atomic_long_dec(&shared_variable);printk(KERN_INFO "Thread: Decremented shared variable to %ld\n", atomic_long_read(&shared_variable));}return 0;
}static int __init atomic_sync_init(void) {// 创建一个简单的内核线程,用于减少共享变量的值struct task_struct *my_thread;my_thread = kthread_run(my_thread_func, NULL, "my_thread");if (IS_ERR(my_thread)) {printk(KERN_ERR "Failed to create thread\n");return PTR_ERR(my_thread);}return 0;
}static void __exit atomic_sync_exit(void) {printk(KERN_INFO "Exiting...\n");
}module_init(atomic_sync_init);
module_exit(atomic_sync_exit);MODULE_LICENSE("GPL");
  • 使用原子操作来实现简单的线程同步机制。
  • 在初始化时,创建一个内核线程,它的工作是每秒减少一次共享变量的值。
  • 由于 atomic_long_dec() 函数是原子的,因此不需要额外的同步手段,就可以确保在多线程环境下对共享变量的操作是安全的。

🐓3.4 资源管理

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/atomic.h>
#include <linux/delay.h>
#include <linux/kthread.h>// 全局的原子长整型变量,用于表示资源数量
static atomic_long_t resource_count = ATOMIC_LONG_INIT(10); // 假设初始资源数量为10// 线程函数,模拟资源的使用和释放
static int resource_manager_func(void *data) {int i;for (i = 0; i < 5; ++i) {msleep(1000);atomic_long_dec(&resource_count); // 使用资源,数量减少1printk(KERN_INFO "Thread: Used resource, remaining count: %ld\n", atomic_long_read(&resource_count));msleep(1000);atomic_long_inc(&resource_count); // 释放资源,数量增加1printk(KERN_INFO "Thread: Freed resource, remaining count: %ld\n", atomic_long_read(&resource_count));}return 0;
}static int __init resource_management_init(void) {// 创建一个内核线程,模拟资源的使用和释放struct task_struct *resource_thread;resource_thread = kthread_run(resource_manager_func, NULL, "resource_thread");if (IS_ERR(resource_thread)) {printk(KERN_ERR "Failed to create resource management thread\n");return PTR_ERR(resource_thread);}return 0;
}static void __exit resource_management_exit(void) {printk(KERN_INFO "Exiting resource management driver...\n");
}module_init(resource_management_init);
module_exit(resource_management_exit);MODULE_LICENSE("GPL");

这篇关于Linux内核之原子操作:atomic_long_dec用法实例(六十七)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/955633

相关文章

Linux实现查看某一端口是否开放

《Linux实现查看某一端口是否开放》文章介绍了三种检查端口6379是否开放的方法:通过lsof查看进程占用,用netstat区分TCP/UDP监听状态,以及用telnet测试远程连接可达性... 目录1、使用lsof 命令来查看端口是否开放2、使用netstat 命令来查看端口是否开放3、使用telnet

MySQL的配置文件详解及实例代码

《MySQL的配置文件详解及实例代码》MySQL的配置文件是服务器运行的重要组成部分,用于设置服务器操作的各种参数,下面:本文主要介绍MySQL配置文件的相关资料,文中通过代码介绍的非常详细,需要... 目录前言一、配置文件结构1.[mysqld]2.[client]3.[mysql]4.[mysqldum

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

Python中yield的用法和实际应用示例

《Python中yield的用法和实际应用示例》在Python中,yield关键字主要用于生成器函数(generatorfunctions)中,其目的是使函数能够像迭代器一样工作,即可以被遍历,但不会... 目录python中yield的用法详解一、引言二、yield的基本用法1、yield与生成器2、yi

深度解析Python yfinance的核心功能和高级用法

《深度解析Pythonyfinance的核心功能和高级用法》yfinance是一个功能强大且易于使用的Python库,用于从YahooFinance获取金融数据,本教程将深入探讨yfinance的核... 目录yfinance 深度解析教程 (python)1. 简介与安装1.1 什么是 yfinance?

Python使用python-pptx自动化操作和生成PPT

《Python使用python-pptx自动化操作和生成PPT》这篇文章主要为大家详细介绍了如何使用python-pptx库实现PPT自动化,并提供实用的代码示例和应用场景,感兴趣的小伙伴可以跟随小编... 目录使用python-pptx操作PPT文档安装python-pptx基础概念创建新的PPT文档查看

MySQL 数据库表操作完全指南:创建、读取、更新与删除实战

《MySQL数据库表操作完全指南:创建、读取、更新与删除实战》本文系统讲解MySQL表的增删查改(CURD)操作,涵盖创建、更新、查询、删除及插入查询结果,也是贯穿各类项目开发全流程的基础数据交互原... 目录mysql系列前言一、Create(创建)并插入数据1.1 单行数据 + 全列插入1.2 多行数据

MySQL 临时表与复制表操作全流程案例

《MySQL临时表与复制表操作全流程案例》本文介绍MySQL临时表与复制表的区别与使用,涵盖生命周期、存储机制、操作限制、创建方法及常见问题,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友跟随小... 目录一、mysql 临时表(一)核心特性拓展(二)操作全流程案例1. 复杂查询中的临时表应用2. 临时

Python库 Django 的简介、安装、用法入门教程

《Python库Django的简介、安装、用法入门教程》Django是Python最流行的Web框架之一,它帮助开发者快速、高效地构建功能强大的Web应用程序,接下来我们将从简介、安装到用法详解,... 目录一、Django 简介 二、Django 的安装教程 1. 创建虚拟环境2. 安装Django三、创

MySQL 数据库表与查询操作实战案例

《MySQL数据库表与查询操作实战案例》本文将通过实际案例,详细介绍MySQL中数据库表的设计、数据插入以及常用的查询操作,帮助初学者快速上手,感兴趣的朋友跟随小编一起看看吧... 目录mysql 数据库表操作与查询实战案例项目一:产品相关数据库设计与创建一、数据库及表结构设计二、数据库与表的创建项目二:员