c++ - 原子读取是否保证读取到最新值?

标签 c++ multithreading atomic volatile stdatomic

在 C++ 中,我们有关键字 volatileatomic 类。它们的区别在于volatile不保证线程安全的并发读写,只是保证编译器不会将变量的值存入缓存,而是直接从内存中加载变量,而atomic保证线程安全的并发读写。

正如我们所知,原子读取操作不可分割,即当一个或多个线程读取变量的值时,两个线程都不能向变量写入新值,所以我认为我们总是读取最新的值,但是我不确定:)

所以,我的问题是:如果我们声明原子变量,我们是否总是在调用load()操作时获取变量的最新值?

最佳答案

if we declare atomic variable, do we always get the latest value of the variable calling load() operation?

是的,对于 latest 的某些定义。

并发的问题是不可能以通常的方式争论事件的顺序。这是由于硬件的一个基本限制,在该硬件中建立跨多个内核的全局操作顺序的唯一方法是将它们序列化(并消除该过程中并行计算的所有性能优势)。

现代处理器提供的是一种选择加入机制,用于在某些操作之间重新建立顺序。原子是该机制的语言级抽象。想象一个场景,其中两个 atomic<int> s ab在线程之间共享(让我们进一步假设它们被初始化为 0 ):

// thread #1
a.store(1);
b.store(1);

// thread #2
while(b.load() == 0) { /* spin */ }
assert(a.load() == 1);

这里的断言保证成立。线程 #2 将观察 a 的“最新”值.

标准没有提到的是循环将在什么时候观察到 b 的值。从 0 更改至 1 .我们知道它会在线程#1 写入之后的某个时间发生,我们也知道它会在写入 a 之后发生。 .但我们不知道过了多久。

当某些写入发生时,允许不同的线程不同意这一事实使这种推理更加复杂。如果你切换到 weaker memory ordering ,一个线程可能会观察到以不同顺序发生的对不同原子变量的写入,这与另一个线程观察到的顺序不同。

关于c++ - 原子读取是否保证读取到最新值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53032354/

相关文章:

c++ - 这种基于线程 ID 的同步是否安全整洁?

clojure - clojure 中惯用的惰性原子

c++ - 在vista中将文件夹挂载为驱动器

c++ - std::move 的类型是什么?

c++ - 根据我对 §3.4.1/8 的解释,这段代码应该可以编译。我错过了什么?

java - 将可运行对象传递给线程 - Java

c++ - 从另一个线程调用 std 容器的大小是否安全?

c++ - 运行英特尔线程构建模块的 XCode 8 环境变量是什么

java - 带字符串参数的线程构造函数有什么用?

c# - 是否可以始终调用而不是检查 InvokeRequired?