linux——原子操作

一、原子操作概念

1. 什么是原子操作?

原子操作 = 不可被中断的操作就像原子是不可分割的最小单位一样。

CPU 执行原子操作时:

  • 一步完成
  • 执行期间不会被线程切换打断
  • 要么完全执行完,要么完全没执行
  • 不会出现 "执行一半被抢走 CPU" 的情况

2. 哪些是原子操作?

  • 简单赋值:a = 100;
  • 简单读取:int b = a;

3. 哪些 不是 原子操作?

这些操作会被线程打断:

  • a = b + 100; (读 → 算 → 写,三步)
  • i++; (读 → 加 → 写)
  • 链表插入、链表删除
  • printf() 不是原子操作(内部复杂)
  • malloc/free 不是原子操作

只要不是一步 CPU 指令,就不是原子操作!

二、为什么非原子操作必须加锁?

因为:非原子操作 = 多步指令 = 可能执行到一半被抢走 CPU一旦被抢走,数据就会错乱、崩溃、覆盖、丢失。

三、用两个示例代码讲清楚

我们以链表头插法为例:

复制代码
newNode->next = head;
head = newNode;

这两行代码 不是原子操作!必须连续执行,不能被打断。

示例代码 1:不加锁(错误!)

复制代码
void* producer(void *arg)
{
    while(1)
    {
        // 创建节点(原子与否不重要)
        Node *newNode = (Node*)malloc(sizeof(Node));
        newNode->data = rand()%100;

        // ==========================
        // 这两行不是原子操作!!!
        newNode->next = head;
        head = newNode;
        // ==========================

        printf("+++product: %d\n", newNode->data);

        sleep(rand()%3);
    }
    return NULL;
}

错误原因:

newNode->next = head;head = newNode;不是原子操作!

两个线程同时执行时,可能:

  • 线程 A 刚执行完第一行

  • CPU 被抢走

  • 线程 B 也修改 head

  • 回来后线程 A 继续执行 → 链表断了、节点丢了、程序崩溃!

结论:

多线程同时操作链表,不加锁 = 程序必定崩溃 / 数据错乱

示例代码 2:加锁(正确!)

复制代码
void* producer(void *arg)
{
    while(1)
    {
        Node *newNode = (Node*)malloc(sizeof(Node));
        newNode->data = rand()%100;

        // 加锁(开始原子区)
        pthread_mutex_lock(&mutex);

        // 这两行被锁保护 → 变成逻辑原子
        newNode->next = head;
        head = newNode;
        printf("+++product: %d\n", newNode->data);

        // 解锁
        pthread_mutex_unlock(&mutex);

        sleep(rand()%3);
    }
    return NULL;
}

锁把两行代码变成 "逻辑原子操作"

  • 同一时间只有一个线程能执行
  • 执行时不会被其他线程打断
  • 要么两行都执行完,要么都不执行
  • 链表永远安全、不会崩溃、不会断链

四、核心总结

  1. 原子操作:不可被中断的一步操作
  2. 多步操作(链表增删、i++)不是原子操作
  3. 非原子操作在多线程下必须加锁
  4. 锁可以让多步指令变成 "逻辑上的原子操作"
  5. 不加锁 = 线程切换打断 = 数据混乱 / 程序崩溃
  6. 加锁 = 安全执行 = 逻辑原子
相关推荐
HLC++15 小时前
Linux的进程间通信
android·linux·服务器
华清远见IT开放实验室16 小时前
实验室建设案例 | 石家庄科技信息职业学院嵌入式实验室——从底层硬件到系统应用,一所应用型高校的嵌入式人才培养这样落地
linux·arm开发·stm32·嵌入式硬件·高校·实验室建设
groundhappy19 小时前
idalib安装和codex ida-mcp配置
linux·开发语言·python
通信小小昕19 小时前
Ubuntu 26.04 中文输入法安装
linux·运维·ubuntu
张小姐的猫20 小时前
【Linux】网络编程 —— HTTP协议(上)
linux·运维·服务器·网络·http·单例模式·策略模式
栩栩云生21 小时前
AI 写代码犯的错,早被写进了错题集
linux·安全·ai编程
imc.111 天前
linux基础IO
linux·运维·服务器
BelongPanda1 天前
Linux Nginx 纯手动 Let‘s Encrypt 泛域名证书配置教程
linux·nginx
酷可达拉斯1 天前
Linux操作系统-shell编程(0)
linux·运维·服务器·python·云计算
2301_777998341 天前
Linux中断机制:操作系统如何高效运行
linux·运维·服务器