You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Linux GCC下用C11 <stdatomic.h>实现int变量原子读写?

在Linux+GCC下用C11 <stdatomic.h>实现int原子读写的最简方案

嘿,这个问题抓得特别准——多线程里随便假设普通变量读写是原子的,绝对是踩坑的常客!好在C11的<stdatomic.h>给了标准的解决方案,结合GCC在Linux下的支持,实现起来其实很直接。

我一步步给你拆解:

1. 先把普通int改成原子类型

首先,你不能再用普通的int来声明messageBox了,得换成标准原子类型atomic_int。这是基础,因为只有原子类型的操作才能被编译器和硬件保证原子性:

#include <stdatomic.h>

// 把原来的int数组改成atomic_int数组
atomic_int messageBox[YOUR_SIZE];

如果是全局变量或者静态变量,初始化可以用ATOMIC_VAR_INIT宏:

atomic_int messageBox[5] = {ATOMIC_VAR_INIT(0), ATOMIC_VAR_INIT(0), ...};

2. 原子赋值操作(替换messageBox[i] = 2)

普通的赋值=对于原子类型虽然GCC可能允许,但标准里更推荐用atomic_store函数来明确表达原子写入的意图,避免编译器优化出问题:

// 原子写入值2到messageBox[i],默认用最严格的内存顺序(memory_order_seq_cst)
atomic_store(&messageBox[i], 2);

如果你对内存顺序有更轻量的需求(比如不需要全局的内存可见性排序),可以指定第三个参数,比如memory_order_relaxed,但新手阶段用默认的seq_cst最安全,不会因为内存模型的细节踩坑。

3. 原子读取+判断操作(替换if (messageBox[i] == 2))

同样,不能直接读取原子变量的内容,要用atomic_load来做原子读取:

// 原子读取messageBox[i]的值,然后判断是否等于2
if (atomic_load(&messageBox[i]) == 2) {
    // 你的逻辑代码
}

这里atomic_load同样默认用memory_order_seq_cst,保证读取到的是最新的、其他线程写入的值。

完整小例子

给你写个简单的多线程示例,一个线程写原子变量,另一个线程读:

#include <stdio.h>
#include <pthread.h>
#include <stdatomic.h>

#define BOX_SIZE 3
atomic_int messageBox[BOX_SIZE] = {ATOMIC_VAR_INIT(0), ATOMIC_VAR_INIT(0), ATOMIC_VAR_INIT(0)};

void* writer_thread(void* arg) {
    int idx = *(int*)arg;
    // 原子赋值
    atomic_store(&messageBox[idx], 2);
    printf("Writer thread: set messageBox[%d] to 2\n", idx);
    return NULL;
}

void* reader_thread(void* arg) {
    int idx = *(int*)arg;
    // 循环等待直到读取到2
    while (atomic_load(&messageBox[idx]) != 2) {
        // 可以加个sleep或者空循环,这里为了简化用空循环
    }
    printf("Reader thread: detected messageBox[%d] is 2\n", idx);
    return NULL;
}

int main() {
    pthread_t writer, reader;
    int idx = 1;

    pthread_create(&writer, NULL, writer_thread, &idx);
    pthread_create(&reader, NULL, reader_thread, &idx);

    pthread_join(writer, NULL);
    pthread_join(reader, NULL);

    return 0;
}

编译的时候记得加上-std=c11(或者-std=gnu11如果你需要GNU扩展)和-pthread链接线程库:

gcc -std=c11 -pthread atomic_demo.c -o atomic_demo

额外提醒

  • GCC从4.7版本开始支持C11的<stdatomic.h>,所以确保你的编译器版本足够新。
  • 原子操作的内存顺序是个进阶知识点,如果你的场景对性能要求极高,可以研究memory_order_relaxed、memory_order_acquire/memory_order_release等,但新手先坚持默认的seq_cst就好,正确性优先。
  • 不要试图自己用volatile来模拟原子操作——volatile只能防止编译器优化,但不保证硬件层面的原子性和内存可见性,完全是两回事!

内容的提问来源于stack exchange,提问作者Theo d'Or

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 09:12:45