在C#中," atomic"意思?

时间:2016-08-02 13:57:15

标签: c#

我在C#6.0和.NET 4.6框架中读到了这个:

  

“赋值和简单算术运算不是原子的”。

那么,它究竟意味着什么?

2 个答案:

答案 0 :(得分:10)

原子操作是不能在中途中断的操作,例如通过线程。举个例如声明

_value++;

如果您有两个线程同时执行此代码且起始值为0,则可能具有以下内容

  • 线程A读取_value,0
  • 主题A添加1,1
  • 主题B读取_value,0
  • 线程B添加1,1
  • 主题A分配给_value,1
  • 主题B分配给_value,1

所以现在,即使我们调整了两次增量,_value中的最终值为1,而不是预期的2。这是因为增量运算符原子。

函数Interlocked.Increment,但原子,所以用

代替上面的代码
Interlocked.Increment(ref _value);

将解决给定的竞争条件。

答案 1 :(得分:6)

原子是不可分割的。原子操作是不可分割的"操作,不能分割,例如中断。

微处理器不按顺序执行,即指令后指令,就像在程序中写入一样。有外部对象,可以改变执行流程。一个很好的例子是中断。

因此,您可能知道MOV指令,该指令几乎适用于所有处理器 想象一下,它是由CPU执行的。将32位值移入32位寄存器 现在,在移动了16位之后,发生了中断请求。

  • 原子MOV指令不会停止但会执行到最后然后 CPU将处理中断
  • 非原子的MOV指令将立即停止并执行中断。问题是,如果中断访问了由MOV写入的寄存器,内容不清楚,因为MOV操作只完成了一半!

现在,在通常的处理器上,MOV对处理器的字大小进行操作是原子的。如果处理器字是16位宽,则16位MOV指令将是原子的 但是,32位MOV操作不是原子操作。这种非原子MOV指令通常不是由指令集提供的,而是由一些高级语言提供的,如C long long或C#' long。这些数据类型的操作保证是原子的!