全局变量和线程

时间:2012-09-25 21:11:35

标签: multithreading synchronization

如果我有一个全局计数器,并且我有两个线程,每个线程在循环中递增100次,为什么我可以有一个200以外的值?我不知道如何访问变量是非原子的。

1 个答案:

答案 0 :(得分:2)

这是因为对于大多数环境来说,增加内存位置不是原子操作。

事件的顺序类似于

  • 编译器将值0置于内存地址0xABCD
  • 线程1将0xABCD读入寄存器并递增寄存器值
  • 线程1被线程2
  • 中断
  • 线程2从存储器地址0xABCD读取值0到寄存器
  • 线程2递增寄存器中的值
  • 线程2将寄存器中的值写入0xABCD
  • 线程2从0xABCD读取值1,递增寄存器,然后再写回
  • 线程1恢复
  • 线程1将其寄存器1中的值写入0xABCD,覆盖线程2之前写入的值2。

要确保结果一致,必须使增量操作成为原子。这通常通过在增量操作周围放置一个线程锁来完成。例如,在C#中可能看起来像

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

或者,在.NET环境中,可以使用Interlocked.Increment

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

其他环境也有类似的结构。

我在.NET环境中遇到线程的最佳参考(但无论您的环境如何,都是有用的读取)如下

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