在 C# 中访问bool字段是原子的吗?特别是,我是否需要锁定:
class Foo
{
private bool _bar;
//... in some function on any thread (or many threads)
_bar = true;
//... same for a read
if (_bar) { ... }
}
在 C# 中访问bool字段是原子的吗?特别是,我是否需要锁定:
class Foo
{
private bool _bar;
//... in some function on any thread (or many threads)
_bar = true;
//... same for a read
if (_bar) { ... }
}
是的。
以下数据类型的读写是原子的:bool、char、byte、sbyte、short、ushort、uint、int、float 和引用类型。
在C# Language Spec中找到。
编辑:理解volatile关键字可能也值得。
如上所述,bool
它是原子的,但您仍然需要记住,它还取决于您想用它做什么。
if(b == false)
{
//do something
}
不是原子操作,这意味着b
在当前线程执行if
语句之后的代码之前, 的值可能会发生变化。
bool 访问确实是原子的,但这还不是全部。
您不必担心读取“未完全写入”的值-在任何情况下都不清楚这可能对 bool 意味着什么-但您确实必须担心处理器缓存,至少如果详细信息时机是一个问题。如果在核心 A 上运行的线程 #1 有您的_bar
in 缓存,_bar
并由运行在另一个核心上的线程 #2 更新,则线程 #1 不会立即看到更改,除非您添加锁定、声明_bar
为volatile
或显式插入调用以Thread.MemoryBarrier()
使缓存值。
我使用的方法,我认为是正确的,是
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 布尔值上是合适的。