多线程读取全局变量 (在无锁状态下 会造成多少种值的出现) -电脑资料

电脑资料 时间:2019-01-01 我要投稿
【www.unjs.com - 电脑资料】

   

int global = 0;// thread 1for(int i = 0; i< 10; ++i)global -= 1;// thread 2for(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, %eaxaddl $1, %eaxmovl %eax, global;linux下减操作movl global, %eaxsubl $1, %eaxmovl %eax, global

    可见,不论加减都要经过global的值加载到eax,然后eax加减1,最后再写回global中。这时如果线程1的global的值刚加载到eax中,线程2获取到了执行权,就会出现问题。具体看下面例子。

    假设操作前global值为5,

电脑资料

多线程读取全局变量 (在无锁状态下 会造成多少种值的出现)》(https://www.unjs.com)。

    线程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,但是寄存器只有一个,如果不使用锁的时候,两个线程读取的都是同一个寄存器。这样会造成全局值的值很多种

最新文章