是 C# 中的 bool 读/写原子
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/59422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is a bool read/write atomic in C#
提问by dbkk
Is accessing a boolfield atomic in C#? In particular, do I need to put a lock around:
在 C# 中访问bool字段是原子的吗?特别是,我是否需要加锁:
class Foo
{
private bool _bar;
//... in some function on any thread (or many threads)
_bar = true;
//... same for a read
if (_bar) { ... }
}
采纳答案by Larsenal
Yes.
是的。
Reads and writes of the following data types are atomic: bool, char, byte, sbyte, short, ushort, uint, int, float, and reference types.
以下数据类型的读取和写入是原子的:bool、char、byte、sbyte、short、ushort、uint、int、float 和引用类型。
as found in C# Language Spec.
如在C# Language Spec 中找到的那样。
Edit: It's probably also worthwhile understanding the volatilekeyword.
编辑:理解volatile关键字可能也是值得的。
回答by McKenzieG1
bool accesses are indeed atomic, but that isn't the whole story.
bool 访问确实是原子的,但这还不是全部。
You don't have to worry about reading a value that is 'incompletely written' - it isn't clear what that could possibly mean for a bool in any case - but you do have to worry about processor caches, at least if details of timing are an issue. If thread #1 running on core A has your _bar
in cache, and _bar
gets updated by thread #2 running on another core, thread #1 will not see the change immediately unless you add locking, declare _bar
as volatile
, or explicitly insert calls to Thread.MemoryBarrier()
to invalidate the cached value.
您不必担心读取“未完全写入”的值 - 在任何情况下都不清楚这对 bool 可能意味着什么 - 但您必须担心处理器缓存,至少如果细节时间是个问题。如果在内核 A 上运行的线程 #1 有您_bar
的缓存,并且_bar
被另一个内核上运行的线程 #2 更新,则线程 #1 将不会立即看到更改,除非您添加锁定、声明_bar
为volatile
或显式插入调用Thread.MemoryBarrier()
以使缓存值。
回答by Dror Helper
As stated above bool is atomic but you still need to remeber that it also depends on what you want to do with it.
如上所述 bool 是原子的,但你仍然需要记住它也取决于你想用它做什么。
if(b == false)
{
//do something
}
is not an atomic operation meaning that b value could change before the current thread executes the code after the if statement.
不是原子操作,这意味着 b 值可能会在当前线程执行 if 语句之后的代码之前更改。
回答by stux
the approach I have used, and I think is correct, is
我使用的方法,我认为是正确的,是
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;
}
}
}
the goal was basically to avoid having to repetively lock an object on every iteration just to check if we needed to lock it in order to provide a large amount of state change information which occurs rarely. I thinkthis approach works. And if absolute consistancy is required, I thinkvolatile would be appropriate on the b bool.
我们的目标基本上是避免在每次迭代中重复锁定一个对象只是为了检查我们是否需要锁定它以提供大量很少发生的状态更改信息。我认为这种方法有效。如果需要绝对一致性,我认为volatile 在 b bool 上是合适的。