linux内核中的原子操作_linux内核原理与分析

[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:?

参考链接

  • 官方文档