linux内核中的原子操作_linux内核原理与分析
文章标签:
linux c函数
[TOC]
问题描述:
内核中的原子操作方法
日志
添加打印日志信息
分析步骤
第1步:
第2步:
...
代码片段
原子操作的作用和存在原因
原子操作的作用:
保证对共享资源的操作是 "不可分割" 的,要么完全执行,要么完全不执行
防止多线程 / CPU 核心并发访问共享资源时出现数据不一致
例如:在多线程环境下对计数器进行加减操作,避免出现计数错误
为什么需要原子操作:
现代 CPU 多核心、多线程并行执行,共享内存访问可能导致竞态条件
一个简单的i++操作在汇编层面会分解为 "读取 - 修改 - 写入" 三个步骤
没有原子性保证时,多线程并发执行可能导致中间结果被覆盖
示例:两个线程同时执行i++(初始 i=0)
线程 1 读取 i=0
线程 2 读取 i=0
线程 1 修改为 1 并写入
线程 2 修改为 1 并写入
最终结果 i=1,而非预期的 2
/*
* @Author: your name
* @Date: 2025-09-02 16:51:16
* @LastEditTime: 2025-09-02 17:00:08
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \linux-4.14.143\drivers\gpu\drm\test\atomic.c
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/atomic.h>
// 定义32位原子变量
static atomic_t atomic_val;
// 演示原子操作的核心函数
static void demo_atomic_operations(void)
{
int ret;
int val;
// 1. 原子变量初始化
atomic_set(&atomic_val, 10);
// 初始化原子变量为 0(等价于 atomic_set(&v, 0))
//atomic_t v = ATOMIC_INIT(0);
val = atomic_read(&atomic_val);
pr_info("初始化原子变量: %d\n", val);
// 2. 基本增减操作
atomic_add(5, &atomic_val); // 加5
pr_info("原子加5后: %d\n", atomic_read(&atomic_val));
atomic_sub(3, &atomic_val); // 减3
pr_info("原子减3后: %d\n", atomic_read(&atomic_val));
atomic_inc(&atomic_val); // 加1
pr_info("原子加1后: %d\n", atomic_read(&atomic_val));
atomic_dec(&atomic_val); // 减1
pr_info("原子减1后: %d\n", atomic_read(&atomic_val));
// 3. 比较与操作
// 若 v 的值等于 old,则将其设为 new(返回是否修改成功:1 成功,0 失败)
//int ret = atomic_cmpxchg(&v, old, new);
ret = atomic_cmpxchg(&atomic_val, 12, 20); // 若当前值为12则设为20
pr_info("比较交换: 旧值=%d, 新值=%d\n", ret, atomic_read(&atomic_val));
// 原子地将 v 与 n 交换(返回 v 的旧值)
ret = atomic_xchg(&atomic_val, 0); // 交换值为0,返回旧值
pr_info("交换操作: 旧值=%d, 新值=%d\n", ret, atomic_read(&atomic_val));
atomic_set(&atomic_val, 1);
ret = atomic_dec_and_test(&atomic_val); // 减1并检查是否为0
pr_info("减1并测试是否为0: 结果=%s (值=%d)\n",
ret ? "是" : "否", atomic_read(&atomic_val));
}
static int __init atomic_simple_init(void)
{
pr_info("=== 简化版原子操作演示开始 ===\n");
demo_atomic_operations();
pr_info("=== 简化版原子操作演示完成 ===\n");
return 0;
}
static void __exit atomic_simple_exit(void)
{
pr_info("原子操作驱动卸载\n");
}
module_init(atomic_simple_init);
module_exit(atomic_simple_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simplified 32-bit Atomic Operations Demo");
图片
结论
输出结论
待查资料问题
- 问题 1:?
- 问题 2:?
参考链接
- 官方文档