原始数据类型是c#atomic(线程安全)吗?

时间:2010-03-12 15:36:07

标签: c# atomic primitive thread-safety

例如,我需要在多线程时锁定bool值吗?

4 个答案:

答案 0 :(得分:17)

没有原子类型这样的东西。只有操作可以是原子的。

读取和写入适合单个字的数据类型(32位处理器上的int,64位处理器上的long)在技术上是“原子的”,但是抖动和/或处理器可以决定重新排序指令,从而创建意外的竞争条件,因此您需要使用lock序列化访问,使用Interlocked类进行写入(在某些情况下读取),或声明变量volatile

简短的回答是:如果两个不同的线程可以访问同一个字段/变量,并且其中至少有一个将要写入,则需要使用某种锁定。对于通常为Interlocked类的原始类型。

答案 1 :(得分:2)

类似问题here

  

对于明确的答案,请转到   规范。 :)

     

CLI的分区I,第12.6.6节   规范说:“符合要求的CLI应   保证读写访问权限   正确对齐内存位置   不大于原生单词大小   所有写入访问时的原子   一个位置大小相同。“

     

这样就确认了s_Initialized   永远不会不稳定,那就读了   并写入primitve类型是   原子。

     

联锁会造成内存障碍   防止处理器   重新排序读取和写入。锁   创造了唯一需要的障碍   这个例子。

     

约翰。

基本上,你不会因为没有锁定bool而出现“崩溃”问题。您可能拥有的是更新或读取布尔顺序的竞争条件。如果你想要以特定的顺序写入/读取bool,那么你需要使用某种锁定机制。

答案 2 :(得分:2)

排序。关于这个here有一个很好的线程,但是短版本是,虽然给定的读或写可能是原子的,但这几乎不是你正在做的事情。例如,如果要增加整数,则需要1)读取值,2)将值加1,然后3)将值存回。任何这些操作都可能被中断。

这就是“Interlocked”等课程的原因。

答案 3 :(得分:0)

静态基元类型是线程安全的,因此您不需要锁定那些类型化的变量。但是,不保证基本类型的任何实例变量。见这里:Are primitive types like bool threadsafe ?

MSDN PrimitiveType Class

这是另一个有用的链接,我也觉得解决方案非常引人注目:SO问题:How do I know if a C# method is thread safe?