是C#中的bool读/写原子

时间:2020-03-05 18:52:21  来源:igfitidea点击:

在C#中访问布尔字段原子吗?特别是,我是否需要加锁:

class Foo
{
   private bool _bar;

   //... in some function on any thread (or many threads)
   _bar = true;

   //... same for a read
   if (_bar) { ... }
}

解决方案

回答

是的。

Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types.

如在语言规范中找到的。

编辑:这也许也值得理解volatile关键字。

回答

布尔访问确实是原子的,但这还不是全部。

我们不必担心读取的是"未完全写入"的值,尽管在任何情况下都不清楚这对于bool可能意味着什么,但是我们确实需要担心处理器缓存,至少在计时细节是一个问题。如果在内核A上运行的线程#1在缓存中有_bar,并且在另一个内核上运行的线程#2更新了_bar,则线程1将不会立即看到更改,除非我们添加锁定,将_bar声明为volatile,或者显式插入对Thread.MemoryBarrier()的调用以使缓存的值无效。

回答

如上所述,布尔是原子的,但是我们仍然需要记住,布尔也取决于我们要如何处理。

if(b == false)
{
    //do something
}

不是
原子操作,意味着b值可能会在当前线程执行if语句之后的代码之前更改。