我们都知道,windows是一个抢占式的多线程环境,因此系统可能会在任意时刻暂停一个线程,切换到另一个线程让新的线程继续执行。请看这段代码:
2个线程函数,各有一个for循环,1000W次,那么,我们或许会认为,最终输出的 g_x的值会是 1000W+1000W = 20000000?
但是,在多线程环境下,是不会达到我们想要的效果的,代码可能不会严格按照我们想要的顺序执行,但线程函数1的一个时间片用完,它或许会去执行线程函数2
汇编代码是这样的:
MOV EAX,[g_x]
INC EAX
MOVE EAX,[g_x]
INC EAX
MOV [g_x],EAX
MOV [g_x],EAX
是的,有可能某次或者某几次的 g_x++的操作会被分解,打断(解释下:INC EAX 以后,没有按照预想的继续执行 MOV [g_x],EAX,而是跳转到另外的一个线程,去执行 MOVE EAX,[g_x])
因此,我们需要有一种方法能够保证对一个值的递增操作是原子操作:也就是说,操作不会被打断
我们可以用如下函数
LONG __cdecl InterlockedExchangeAdd( __in_out LONG volatile* Addend, __in LONG Value );
修改后的代码如下:
这样,我们就可以得到正确的结果了!2000W