在C#中访问 bool 字段是否为原子?特别是,我需要锁定:
class Foo
{
private bool _bar;
//... in some function on any thread (or many threads)
_bar = true;
//... same for a read
if (_bar) { ... }
}
答案 0 :(得分:107)
是强>
以下数据类型的读写是原子的:bool,char,byte,sbyte,short,ushort,uint,int,float和reference类型。
在C# Language Spec中找到。
编辑:理解volatile关键字也是值得的。
答案 1 :(得分:44)
如上所述bool是原子的,但你仍需要记住它还取决于你想用它做什么。
if(b == false)
{
//do something
}
不是 原子操作意味着b值可以在当前线程在if语句之后执行代码之前改变。
答案 2 :(得分:26)
bool访问确实是原子的,但这不是全部。
您不必担心读取“未完全写入”的值 - 在任何情况下都不清楚boo可能意味着什么 - 但您必须担心处理器缓存,至少如果计时的细节是一个问题。如果在核心A上运行的线程#1在缓存中具有_bar
,并且_bar
由在另一个核心上运行的线程#2更新,则线程#1将不会立即看到更改,除非您添加锁定,声明_bar
为volatile
,或明确插入对Thread.MemoryBarrier()
的调用以使缓存的值无效。
答案 3 :(得分:0)
我使用的方法,我认为是正确的,是
volatile bool b = false;
.. rarely signal an update with a large state change...
lock b_lock
{
b = true;
//other;
}
... another thread ...
if(b)
{
lock b_lock
{
if(b)
{
//other stuff
b = false;
}
}
}
目标基本上是避免必须在每次迭代时重复锁定一个对象,只是为了检查我们是否需要锁定它以便提供很少发生的大量状态变化信息。我认为这种方法有效。如果需要绝对一致性,我认为 volatile适用于b bool。