int global = 0; // thread 1 for(int i = 0; i < 10; ++i) global -= 1; // thread 2 for(int i = 0; i < 10; ++i) global += 1;之后global的可能的值是多少(多种可能)?
这个问题考虑的是全局变量global的加减操作不是原子操作,在加减过程中有可能被打断,从而产生的结果与预期不一样。上述global加减操作的汇编如下
;windows下加操作 mov eax,dword ptr [globle (10A9148h)] add eax,1 mov dword ptr [globle (10A9148h)],eax ;windows下减操作 mov eax,dword ptr [globle (10A9148h)] sub eax,1 mov dword ptr [globle (10A9148h)],eax ;linux下加操作 movl global, %eax addl $1, %eax movl %eax, global ;linux下减操作 movl global, %eax subl $1, %eax movl %eax, global
假设操作前global值为5。
线程1 线程2
movl global,%eax;global值为5,%eax值为5
addl $1,%eax;%eax值为6
------此时线程2获取执行权限--------->
movl global,%eax;global值为5,%eax值为5
subl $1,%eax;%eax值为4
movl %eax,global;%eax值为4,global值为4
<--------执行权交回线程1--------------
movl %eax,global;%eax值为4,global值为4
由上述例子可以看出,结果并非我们预计的global的值加1减1后仍保持原值,而是由5变为了4。这就是多线程下非原子操作有可能产生的问题。
所以题目global输出并非0一种可能。global的加减操作有可能失效,所以global的结果应分布在-10到10之间。
需要明白的对于硬件来说,虽说在操作一个值global,但是寄存器只有一个,如果不使用锁的时候,两个线程读取的都是同一个寄存器。这样会造成全局值的值很多种
原文地址:http://blog.csdn.net/yusiguyuan/article/details/42681267