假设在一个多线程单CPU的环境中,有一个记录所有核心对象数量的变量nKernelObject,这个变量可以被所有的线程共享。假设线程A创建了一个核心对象,并假设nKernelObject当前的值为100,这时候,该线程需要增加这个变量的值来反映这种情况(核心对象数量增加),于是可能会通过下列代码进行修改:
如果被编译成汇编语言,可能是下面这样:
假设在上述第二条指令(inc eax)完成后,该线程的时间片用完,被临时阻塞,由于nKernelObject的值还没有被修改,所以仍然是100,但eax寄存器的值已经是101了。线程A被阻塞后,另外一个线程B被唤醒继续运行,而线程B同样创建了一个核心对象,也需要对nKernelObject进行递增。这时候,在线程B中会执行同样的代码。假设线程B在执行完上述最后一条指令(mov nKernelObject,eax)后,时间片用完,被阻塞。这时候,B修改了nKernelObject,使得nKernelObject变成了101,而不是原来的100。然后线程A又被唤醒,继续运行,由于线程A被挂起的时候,刚刚执行完inc eax指令,所以线程A会继续执行mov nKernelObject,eax指令,这样原先存储在eax内的值(101)就覆盖了当前nKernelObject的值,因此当前nKernelObject的值仍然是101,于是不一致就产生了(正确的情况下nKernelObject应该是102)。(www.xing528.com)
可以看出,产生上述问题的原因,就是线程A在修改nKernelObject变量时,被打断了。因此,为了解决这个问题,必须确保线程A在修改nKernelObject变量的时候,作为一个原子操作进行,不能被打断,即把上述修改nKernelObject的区域作为一个关键区域来对待。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。