Dav*_*ine 11 c# multithreading boolean atomic volatile
在C#中,我们知道a bool
是原子的 - 那么为什么将它标记为有效volatile
呢?有什么不同,什么是一个好的(甚至是实际的)用例?
bool _isPending;
Run Code Online (Sandbox Code Playgroud)
与
volatile bool _isPending; // Is this realistic, or insanity?
Run Code Online (Sandbox Code Playgroud)
我在这里和这里做了一些阅读,我正在努力确保我完全理解两者的内部运作.我想知道什么时候使用一个与另一个相比,或者只是bool
足够.
Eri*_*ert 17
在C#中,我们知道bool是原子的 - 那么为什么将它标记为volatile是有效的呢?有什么不同,什么是一个好的(甚至是实际的)用例?
您的问题的假设是您认为volatile
使访问成为原子.但是波动性和原子性是完全不同的东西,所以不要把它们混为一谈.
波动性是限制编译器和运行时进行某些优化的属性,这些优化涉及相对于彼此向前和向后移动读取和写入变量,更一般地说,关于其他重要事件(如启动和停止线程),运行构造函数,等等.有关可见副作用可能会或可能不会重新排序操作的详细列表,请参阅C#规范.
原子性是特定操作只能被观察为未开始或完全完成,并且从未"中途完成"的属性.
从定义中可以看出,这两件事与彼此没有任何关系.
在C#中,对引用,bools和大小为4或更小的整数类型的所有访问都保证是原子的.
现在,在C#中,原子性和波动性之间存在一些轻微的非正交性,因为只有原子类型的字段可能被标记为易失性.例如,你可能不会制造挥发性的双倍.说"我们将限制读写如何优化但仍然允许撕裂"将是非常奇怪和危险的.由于波动性不会导致原子性,因此您不希望让用户认为操作是原子的,因为它也是不稳定的.
您应该阅读我的一系列文章,这些文章更详细地解释了这些事物之间的差异,实际上是什么样的波动,以及为什么你几乎不能理解安全地使用它.
https://ericlippert.com/2011/05/26/atomicity-volatility-and-immutability-are-different-part-one/
https://ericlippert.com/2011/05/31/atomicity-volatility-and-immutability-are-different-part-two/
https://ericlippert.com/2011/06/16/atomicity-volatility-and-immutability-are-different-part-three/
http://blog.coverity.com/2014/03/12/can-skip-lock-reading-integer/
如果您认为在阅读完所有内容后了解波动性,我邀请您尝试解决我在此提出的难题:
如果先前或后续代码中的变量有更新,并且更新发生的顺序很关键,则将该字段标记为,volatile
将确保对该字段的更新将在任何先前的更新之后和任何后续的更新之前发生。
换句话说,如果_isPending
为is volatile
,则编译器将不会使这些指令以不同的顺序执行:
_someVariable = 10;
_isPending = true;
_someOtherVariable = 5;
Run Code Online (Sandbox Code Playgroud)
无论是多线程还是非多线程,如果我们根据相邻行中的这些更新是否按照指定的顺序进行编写而导致代码中断,则可能是错误的。我们应该问为什么这个顺序很重要。(如果有一种情况很重要,请想象一下尝试在注释中进行解释,以使没有人对代码进行重大更改。)
对于几乎所有阅读以上代码的人来说,这些操作的顺序似乎都没有关系。如果它们确实很重要,则意味着其他阅读我们代码的人可能无法理解正在发生的事情。他们可能会进行一些重构,重新排列这些代码行,并在不知情的情况下破坏一切。当他们对其进行测试时,它甚至可以工作,然后在部署时意外地和不一致地失败。
坦白说,我不鼓励您从事不稳定的领域。易失性字段表明您正在疯狂地做某事:您试图在两个不同的线程上读取和写入相同的值,而没有进行锁定。
我想我没有直接回答方向。volatile
对一种类型(包括bool
)有效,因为可以对该类型执行原子操作。volatile
防止编译器优化。根据有关的文档volatile
,
这样可以确保始终在字段中显示最新值。
但是,如果该字段不能用32位或更少的位数表示,那么阻止编译器优化就无法保证这一点。
归档时间: |
|
查看次数: |
1378 次 |
最近记录: |