Global variables and threads

眉间皱痕 提交于 2019-12-23 04:55:07

问题


If I have a global counter and I have two threads that are each incrementing it 100 times in a loop, why is it possible that I can have a value other than 200? I don't see how accessing the variable is nonatomic.


回答1:


That is because for most environments, incrementing a memory location is not an atomic operation.

The sequence of events would be something like

  • The compiler places the value 0 at the memory address 0xABCD
  • Thread 1 reads 0xABCD into a register and increments the register value
  • Thread 1 is interrupted by Thread 2
  • Thread 2 reads the value 0 from the memory address 0xABCD into a register
  • Thread 2 increments the value in the register
  • Thread 2 writes the value from the register to 0xABCD
  • Thread 2 reads the value 1 from 0xABCD, increments the register, and writes back again
  • Thread 1 resumes
  • Thread 1 writes the value from its register, 1, to 0xABCD, overwriting the value 2 that Thread 2 had previously written there.

To ensure a consistent result, you must make the increment operation atomic. This is often done by placing a thread lock around the increment operation. For example, in C# that might look like

object mylock = new object();
...
lock (mylock) 
{ 
    myInt++;
}

Alternatively, in the .NET environment, one could use Interlocked.Increment

http://msdn.microsoft.com/en-us/library/dd78zt0c.aspx

Other environments have similar constructs.

The best reference I have ever come across for threading in the .NET environment (but is a useful read no matter what your environment) is the following

http://www.albahari.com/threading/



来源:https://stackoverflow.com/questions/12591132/global-variables-and-threads

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!