例如,我需要在多线程时锁定bool
值吗?
答案 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 ?
这是另一个有用的链接,我也觉得解决方案非常引人注目:SO问题:How do I know if a C# method is thread safe?