x++的故事


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

答案 不是 x++由3条指令完成 。x++在单CPU下不是原子操作。
对应3条汇编指令
movl x, %eax
addl $1, %eax
movl %eax, x
在vc2005下对应
++x;
004232FA mov eax,dword ptr [x]
004232FD add eax,1
00423300 mov dword ptr [x],eax
仍然是3条指令。

所以++x,x++等都不是原子操作。因其步骤包括了从内存中取x值放入寄存器,加寄存器,把值写入内存三个指令


面试题:i初始值为0,i++在两个线程里边分别执行100次,能得到的最大值和最小值分别是多少?

得到最大值必然是200,一切有序进行。

最小值呢?

i++可以理解为三步,

r=x;

r=r+1;

x=r;

取值存入寄存器,寄存器自增,寄存器值赋给x(不同线程的寄存器是独立的)



我的理解:

假设当前有线程1和线程2,线程2先运行第一步,r2=0,x=0

线程1运行i++99次,r1=99,x=99

线程2运行第二步、第三步,r2=1,x=1

线程1运行第100次i++的第一步、第二步,r1=2,x=1

线程2运行完所有

线程1运行第100次i++的第三步,r1=2,x=2


网上的说法(也很好):

如此,假设两个线程的执行步骤如下: 


 1. 线程A执行第一次i++,取出内存中的i,值为0,存放到寄存器后执行加1,此时CPU1的寄存器中值为1,内存中为0;

 2. 线程B执行第一次i++,取出内存中的i,值为0,存放到寄存器后执行加1,此时CPU2的寄存器中值为1,内存中为0;

 3. 线程A继续执行完成第99次i++,并把值放回内存,此时CPU1中寄存器的值为99,内存中为99;

 4. 线程B继续执行第一次i++,将其值放回内存,此时CPU2中的寄存器值为1,内存中为1;

 5. 线程A执行第100次i++,将内存中的值取回CPU1的寄存器,并执行加1,此时CPU1的寄存器中的值为2,内存中为1;

 6. 线程B执行完所有操作,并将其放回内存,此时CPU2的寄存器值为100,内存中为100; 

 7. 线程A执行100次操作的最后一部分,将CPU1中的寄存器值放回内存,内存中值为2;

 8. 结束!

答案:最小值2,最大值200


参考文献

https://software.intel.com/zh-cn/blogs/2010/01/14/cpucpu

http://blog.csdn.net/zmldlut/article/details/8219867






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值