i++是原子操作吗

什么是原子操作?

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

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

  1. #include <stdlib.h>  
  2. #include <pthread.h>  
  3. static int x;  
  4. void inc()  
  5. {  
  6.     x++;  
  7. }  
  8. void foo(void)  
  9. {  
  10.     int i;  
  11.     for (i = 0; i < 5; i++)  
  12.     {  
  13.         inc();  
  14.     }  
  15. }  
  16. int main(int argc, char *argv[])  
  17. {  
  18.     pthread_t p1, p2;  
  19.     pthread_create(&p1, NULL, (void *)foo, NULL);  
  20.     pthread_create(&p2, NULL, (void *)foo, NULL);  
  21.     pthread_join(p1, NULL);  
  22.     pthread_join(p2, NULL);  
  23.     printf("%d/n", x);  
  24. }  
 

代码输出的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。

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值