GNU C中x++是原子操作吗?

本文探讨了GCC编译器中x++操作是否具备原子性,并通过具体代码及汇编指令分析证实其非原子特性,进而引出对多线程环境下变量同步保护的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是原子操作?

所谓原子操作,就是"不可中断的一个或一系列操作" 。在确认一个操作是原子的情况下,多线程环境里面,我们可以避免仅仅为保护这个操作在外围加上性能开销昂贵的锁,甚至借助于原子操作,我们可以实现互斥锁。

那么,GNU C中x++是原子操作吗?请看下面一段代码:

#include <stdlib.h> #include <pthread.h> static int x; void inc() { x++; } void foo(void) { int i; for (i = 0; i < 5; i++) { inc(); } } int main(int argc, char *argv[]) { pthread_t p1, p2; pthread_create(&p1, NULL, (void *)foo, NULL); pthread_create(&p2, NULL, (void *)foo, NULL); pthread_join(p1, NULL); pthread_join(p2, NULL); printf("%d/n", x); }

代码输出的x值是多少呢?

在多线程编程环境中,对全局变量的访问是需要进行同步保护的,当然也可以借用原子操作,这样程序运行结果才是确定的。所以现在的问题是x++是原子操作吗?如果是,则上述代码运行结果x=10。如果不是,则运行结果是不确定的,x值为 [5, 10]范围中的某个值。x++应该是非原子操作,但我又不是很确定,所以只好看汇编代码了。

inc:
pushl %ebp
movl %esp, %ebp
movl x, %eax
addl $1, %eax
movl %eax, x
popl %ebp
ret

从上面的汇编代码片段,显然可以确定x++是非原子的,它由3条汇编指令组成。因此上面的x的值也就是不确定的了,它的最大值可能为10,最小值可能为5。这两种情况分别发生在完全没有同步(即串行)和完全竞争(即每次均同时读取同样的x值)的情况下,两个极端情形,要得到这样的结果,估计要看RP(开个玩笑,呵呵)。

结论,GNU C中x++不是原子操作,所以特别提供了原子值类型atomic_t。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值