C# bool是原子的,为什么volatile有效

标签 c# multithreading boolean atomic volatile

C# 中,我们知道 bool 是原子的 - 那么为什么将其标记为 volatile 是有效的?两者之间有什么区别,什么是好的(甚至实用的)用例?

bool _isPending;

对比

volatile bool _isPending; // Is this realistic, or insanity?

我读了一些书herehere ,并且我正在努力确保我完全理解两者的内部工作原理。我想了解什么时候适合使用一个与另一个,或者是否仅 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/

https://web.archive.org/web/20160323025740/http://blog.coverity.com/2014/03/12/can-skip-lock-reading-integer/

如果您认为在阅读完所有内容后您了解波动性,我邀请您尝试解决我在这里提出的难题:

https://web.archive.org/web/20160729162225/http://blog.coverity.com/2014/03/26/reordering-optimizations/

关于C# bool是原子的,为什么volatile有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38166019/

相关文章:

c# - 将数组转换为多行字符串的最快方法

c# - WPF中窗口再次获得焦点时如何启动方法?

c# - 如何在卸载时从应用程序数据目录中删除文件?

java - 运行时 boolean 值发生变化

python - 要检查 Pandas Dataframe 列是否为 TRUE/FALSE,如果为 TRUE,则检查另一列是否满足条件并生成具有值 PASS/FAIL 的新列

c# - 用 C# 编写驱动程序

java 多线程中的质数问题

java - Java 中阻塞线程的监控和终止

multithreading - 我应该在 Clojure 中使用哪一个?去 block 或线程?

jsp - 如何在从 JSP 向 Action 发送空字符串的 boolean 值中保留 NULL 状态