在 C# 中,我们知道 bool
是原子的 - 那么为什么将其标记为 volatile
是有效的?两者之间有什么区别,什么是好的(甚至实用的)用例?
bool _isPending;
对比
volatile bool _isPending; // Is this realistic, or insanity?
我读了一些书here和 here ,并且我正在努力确保我完全理解两者的内部工作原理。我想了解什么时候适合使用一个与另一个,或者是否仅 bool
就足够了。
最佳答案
In C#, we know that a bool is atomic - then why is it valid to mark it as volatile? what is the difference and what is a good (or even practical) use-case for one versus the other?
你的问题假设是你相信 volatile
使访问成为原子的。但波动性和原子性是完全不同的东西,所以不要将它们混为一谈。
波动性是编译器和运行时被限制进行某些优化的属性,这些优化涉及相对于彼此及时向前和向后移动变量的读取和写入,更一般地说,相对于其他重要事件,例如启动和停止线程、运行构造函数等。请参阅 C# 规范以获取有关如何根据可见的副作用重新排序操作或不重新排序操作的详细列表。
原子性是特定操作只能被观察为未开始或完全完成,而永远不会“半途完成”的属性。
正如您从定义中看到的那样,这两者之间没有任何关系。
在 C# 中,所有对引用、 boolean 值和大小为 4 及更小的整数类型的访问都保证是原子的。
现在,在 C# 中,原子性和易变性之间存在一些轻微的非正交性,因为只有原子类型的字段可以标记为易变性。例如,您可能不会制作 volatile double。说“我们将限制读取和写入的优化方式但仍允许撕裂”真的很奇怪和危险。由于易变性不会导致原子性,因此您不想让用户认为操作是原子性的,只是因为它也是易变的。
您应该阅读我的系列文章,这些文章更详细地解释了这些东西之间的区别,volatile 的实际作用,以及为什么您对安全使用它的了解还不够多。
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/
如果您认为在阅读完所有内容后您了解波动性,我邀请您尝试解决我在这里提出的难题:
关于C# bool是原子的,为什么volatile有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38166019/