多线程编程中 Volatile 的固有局限性
在多线程编程领域,同步对共享数据的访问至关重要。一种方法涉及利用 volatile 关键字来确保变量值的保存。然而,最近的一次讨论引起了人们对 volatile 在这种情况下的功效的担忧。
什么是 Volatile?
Volatile 声明的变量不应从程序。这确保编译器不会将值缓存在寄存器中,而是在每次访问时从内存中获取它。它最初旨在与硬件寄存器或 I/O 操作一起使用,但经常用于多线程编程情况。
多线程中 Volatile 的挑战
不幸的是,易失性在多线程上下文中使用时有局限性。虽然它保证对易失性变量的读取和写入立即发生,并且相对于其他易失性访问以正确的顺序进行,但它并不能阻止围绕易失性访问对非易失性内存访问进行重新排序。
考虑一个全局变量 foo声明为 volatile,由多个线程共享。一个线程以原子方式设置 foo,而另一个线程则读取它。易失性声明确保写入和读取操作不会被优化。但是,编译器仍可能对其他内存操作进行重新排序,例如相对于易失性操作加载非易失性变量。
解决方案:内存屏障和原子变量
为了防止重新排序,需要内存屏障。它们指示编译器和 CPU 确保不会跨过屏障重新排序内存访问。在写入易失性变量之后放置内存屏障可以防止后续非易失性读取相对于易失性写入的重新排序。
但是,由于内存屏障还保证执行所有挂起的读取和写入,因此它们本质上是提供与 volatile 相同的功能。因此,在使用内存屏障时, volatile 关键字就变得不必要了。
C 中的现代替代方案:原子变量
在 C 11 中,原子变量 (std::atomic
以上是Volatile真的能解决多线程同步问题吗?的详细内容。更多信息请关注PHP中文网其他相关文章!