是C#原子的基本算术运算

Sha*_*fiz 4 c# locking arithmetic-expressions thread-safety

基本的算术运算线程安全吗?

例如,如果++对全局变量进行操作(将从不同的线程修改),是否需要锁定它?

例如

void MyThread() // can have many running instances
{
    aGlobal++;
}
Run Code Online (Sandbox Code Playgroud)

或应该是

void MyThread()
{
    lock( lockerObj)
    {
        aGlobal++;
    }
}
Run Code Online (Sandbox Code Playgroud)

Jon*_*Jon 10

规格总结得很好.第5.5节"变量引用的原子性":

以下数据类型的读取和写入是原子的:bool,char,byte,sbyte,short,ushort,uint,int,float和reference类型.此外,在先前列表中具有基础类型的枚举类型的读取和写入也是原子的.其他类型的读写,包括long,ulong,double和decimal,以及用户定义的类型,不保证是原子的.除了为此目的而设计的库函数之外,不保证原子读 - 修改 - 写,例如在递增或递减的情况下.

结论:

  • 独立读/写是原子的(但仅适用于某些数据类型)
  • 读/修改/写(例如i++)永远不是原子的
  • 您可以使用Interlocked类方法在尚未保证的情况下实现原子性

Interlocked功能不够的情况下,除了使用同步原语之外没有其他选择,例如Monitor.Enter(编译器也通过lock语句公开).