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换行符的使用方法详解》本文介绍了Linux中常用的换行符LF及其在文件中的表示,展示了如何使用sed命令替换换行符,并列举了与换行符处理相关的Linux命令,通过代码讲解的非常详细,需要的... 目录简介检测文件中的换行符使用 cat -A 查看换行符使用 od -c 检查字符换行符格式转换将

Linux系统配置NAT网络模式的详细步骤(附图文)

《Linux系统配置NAT网络模式的详细步骤(附图文)》本文详细指导如何在VMware环境下配置NAT网络模式,包括设置主机和虚拟机的IP地址、网关,以及针对Linux和Windows系统的具体步骤,... 目录一、配置NAT网络模式二、设置虚拟机交换机网关2.1 打开虚拟机2.2 管理员授权2.3 设置子

揭秘Python Socket网络编程的7种硬核用法

《揭秘PythonSocket网络编程的7种硬核用法》Socket不仅能做聊天室,还能干一大堆硬核操作,这篇文章就带大家看看Python网络编程的7种超实用玩法,感兴趣的小伙伴可以跟随小编一起... 目录1.端口扫描器:探测开放端口2.简易 HTTP 服务器:10 秒搭个网页3.局域网游戏:多人联机对战4.

Linux系统中卸载与安装JDK的详细教程

《Linux系统中卸载与安装JDK的详细教程》本文详细介绍了如何在Linux系统中通过Xshell和Xftp工具连接与传输文件,然后进行JDK的安装与卸载,安装步骤包括连接Linux、传输JDK安装包... 目录1、卸载1.1 linux删除自带的JDK1.2 Linux上卸载自己安装的JDK2、安装2.1

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

Mysql表的简单操作(基本技能)

《Mysql表的简单操作(基本技能)》在数据库中,表的操作主要包括表的创建、查看、修改、删除等,了解如何操作这些表是数据库管理和开发的基本技能,本文给大家介绍Mysql表的简单操作,感兴趣的朋友一起看... 目录3.1 创建表 3.2 查看表结构3.3 修改表3.4 实践案例:修改表在数据库中,表的操作主要

C# WinForms存储过程操作数据库的实例讲解

《C#WinForms存储过程操作数据库的实例讲解》:本文主要介绍C#WinForms存储过程操作数据库的实例,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、存储过程基础二、C# 调用流程1. 数据库连接配置2. 执行存储过程(增删改)3. 查询数据三、事务处

Linux卸载自带jdk并安装新jdk版本的图文教程

《Linux卸载自带jdk并安装新jdk版本的图文教程》在Linux系统中,有时需要卸载预装的OpenJDK并安装特定版本的JDK,例如JDK1.8,所以本文给大家详细介绍了Linux卸载自带jdk并... 目录Ⅰ、卸载自带jdkⅡ、安装新版jdkⅠ、卸载自带jdk1、输入命令查看旧jdkrpm -qa

Java使用Curator进行ZooKeeper操作的详细教程

《Java使用Curator进行ZooKeeper操作的详细教程》ApacheCurator是一个基于ZooKeeper的Java客户端库,它极大地简化了使用ZooKeeper的开发工作,在分布式系统... 目录1、简述2、核心功能2.1 CuratorFramework2.2 Recipes3、示例实践3

Linux samba共享慢的原因及解决方案

《Linuxsamba共享慢的原因及解决方案》:本文主要介绍Linuxsamba共享慢的原因及解决方案,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux samba共享慢原因及解决问题表现原因解决办法总结Linandroidux samba共享慢原因及解决