c++ - 读取一个在没有锁定的情况下同时修改的整数变量是否安全?

标签 c++ multithreading concurrency

假设我在一个类中有一个整型变量,这个变量可能会被其他线程同时修改。写入受互斥体保护。我也需要保护读取吗?我听说有一些硬件架构,如果一个线程修改一个变量,另一个线程读取它,那么读取结果将是垃圾;在这种情况下,我确实需要保护读取。不过我从未见过这样的架构。

此问题假设单个事务仅包含更新单个整数变量,因此我不担心事务中可能涉及的任何其他变量的状态。

最佳答案

原子读取
如前所述,它依赖于平台。在 x86 上,该值必须在 4 字节边界上对齐。通常对于大多数平台,读取必须在单个 CPU 指令中执行。

优化器缓存
优化器不知道您正在读取由不同线程修改的值。声明值 volatile 有助于实现这一点:优化器将为每次访问发出内存读/写,而不是尝试将值缓存在寄存器中。

CPU 缓存
不过,您可能会读到一个陈旧的值,因为在现代架构上,您有多个内核和单独的缓存,这些缓存不会自动保持同步。您需要一个读取内存屏障,通常是特定于平台的指令。

在 Wintel 上,线程同步函数会自动添加一个完整的内存屏障,或者您可以使用 InterlockedXxxx功能。

MSDN:Memory and Synchronization issues , MemoryBarrier

[编辑] 另请参阅 drhirsch 的评论。

关于c++ - 读取一个在没有锁定的情况下同时修改的整数变量是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1350994/

相关文章:

C++ - OpenMP 任务 - map 插入,关键吗?

c++ - 线程阻塞了整个程序

c++ - 删除指向流的类成员指针的段错误

c++ - 面向对象的C++多线程

java - 如何使用 RestTemplate 为每个请求设置 RequestConfiguration?

java - Java 中的状态相关类是什么?

c# - 使用 CQRS 方法处理并发

c++ - 将按钮放在QT中水平线的中心

c++ - 如何在 visual studio 2019 中修复 "[member variable that is a vulkan struct] is uninitialized. Always initialize a member variable"?

ios - UIKit如何在主线程阻塞时绘制动画的UIActivityIndi​​cator?