Linux线程使用全局变量求和出现异常结果问题咨询
解决多线程累加全局变量的异常结果问题
兄弟我太懂你这种困惑了!当初我第一次写多线程累加逻辑的时候,也碰到过结果和预期对不上的情况,盯着代码看半天都没发现问题——其实你踩的是**多线程竞态条件(Race Condition)**的坑!
问题根源拆解
你写的i++看起来是一行简单的代码,但底层其实是三个独立的操作:
- 从内存读取
i的当前值到CPU寄存器 - 寄存器里的值加1
- 把新值写回内存
当多个线程同时执行这段代码时,很可能出现这种情况:线程A刚读完i的旧值,还没来得及把加1后的新值写回内存,线程B就也读取了同一个旧值,最后两个线程都把相同的新值写回去——相当于白白少加了一次,结果自然不符合预期。
两种靠谱的解决办法
方法一:用互斥锁(pthread_mutex_t)做同步
互斥锁能保证同一时间只有一个线程能执行被锁保护的代码块,彻底避免多个线程同时操作共享变量的冲突。修改后的完整代码示例:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> int i = 5; // 定义全局互斥锁 pthread_mutex_t mutex; void *sum(void *arg) { // 操作共享变量前加锁 pthread_mutex_lock(&mutex); i++; printf("当前线程执行后i的值:%d\n", i); // 操作完成后解锁,让其他线程可以访问 pthread_mutex_unlock(&mutex); pthread_exit(NULL); } int main() { // 初始化互斥锁 pthread_mutex_init(&mutex, NULL); pthread_t tid1, tid2; pthread_create(&tid1, NULL, sum, NULL); pthread_create(&tid2, NULL, sum, NULL); // 等待两个线程执行完毕 pthread_join(tid1, NULL); pthread_join(tid2, NULL); // 销毁互斥锁 pthread_mutex_destroy(&mutex); printf("最终i的值:%d\n", i); return 0; }
方法二:用原子操作(C11标准)
如果你的编译器支持C11标准,可以直接用原子类型替代普通int,这样累加操作会被底层硬件保证是原子的,不需要手动加锁:
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <stdatomic.h> // 定义原子类型的全局变量 atomic_int i = 5; void *sum(void *arg) { // atomic_fetch_add是原子化的加1操作,返回旧值 atomic_fetch_add(&i, 1); printf("当前线程执行后i的值:%d\n", atomic_load(&i)); pthread_exit(NULL); } int main() { pthread_t tid1, tid2; pthread_create(&tid1, NULL, sum, NULL); pthread_create(&tid2, NULL, sum, NULL); pthread_join(tid1, NULL); pthread_join(tid2, NULL); printf("最终i的值:%d\n", atomic_load(&i)); return 0; }
注意事项
编译的时候别忘了链接pthread库,比如用命令:gcc your_code.c -o your_program -pthread,不然会出现编译错误哦!
内容的提问来源于stack exchange,提问作者João
相关产品推荐
相关产品推荐

