gpt4 book ai didi

c++ - std::memory_order_seq_cst 是如何工作的

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:32:55 24 4
gpt4 key购买 nike

我从以下位置获取了有关 std::memory_order_seq_cst 的示例: http://en.cppreference.com/w/cpp/atomic/memory_order

#include <thread>
#include <atomic>
#include <cassert>

std::atomic<bool> x = {false};
std::atomic<bool> y = {false};
std::atomic<int> z = {0};

void write_x()
{
x.store(true, std::memory_order_seq_cst);
}

void write_y()
{
y.store(true, std::memory_order_seq_cst);
}

void read_x_then_y()
{
while (!x.load(std::memory_order_seq_cst))
;
if (y.load(std::memory_order_seq_cst)) {
++z;
}
}

void read_y_then_x()
{
while (!y.load(std::memory_order_seq_cst))
;
if (x.load(std::memory_order_seq_cst)) {
++z;
}
}

int main()
{
std::thread a(write_x);
std::thread b(write_y);
std::thread c(read_x_then_y);
std::thread d(read_y_then_x);
a.join(); b.join(); c.join(); d.join();
assert(z.load() != 0); // will never happen
}

Acquire/Release versus Sequentially Consistent memory order的问题中也提到了这个例子.

我的问题是线程 c 和线程 d 怎么可能看到不同的东西?如果可能的话,为什么下面这个简单的例子总是屈服于 z=3?例如,线程 b 可以说“好吧我看到 0,即使线程 a 已经完成所以 z 再次变为 0+1”

#include <atomic>
#include <iostream>

std::atomic<int> z = {0};

void increment()
{
z.fetch_add(1, std::memory_order_relaxed);
}
int main()
{
std::thread a(increment);
std::thread b(increment);
std::thread c(increment);
a.join(); b.join(); c.join();
std::cout << z.load() << '\n';
}

最佳答案

因此,通过在您的评论中看到不同的内容,您的意思是线程 C 看到 x==1,y==0 并且线程 D 看到 x==0 和 y==1。顺序一致性可能吗?

让我们假设这个总顺序(修改是这个符号化内存状态之间的转换):

{x==0,y==0} : S0
{x==1,y==0} : S1
{x==1,y==1} : S2

当我们说“看到”时,我们的意思是线程可能执行负载。两个加载不能在一个线程中同时执行。那么线程 C 怎么可能看到 x==1 然后 看到 y==0 而线程 D 看到 x==0 然后 看到 y==1?线程 C 在内存处于状态 S1 时执行这两个加载,线程 D 在状态 S0 看到 x,然后在状态 S2 看到 y

在您的示例代码中,线程 C 加载 x 然后加载 y,线程 D 重复加载 y 直到它为真,然后加载 x。所以在 y==1 之后,保证 x==1 在这个总顺序中。

正如 Minee 在其评论中所说,如果使用获取/释放内存顺序代替顺序一致性内存顺序,则不会有任何期望:获取/释放语义并不意味着任何总顺序,而且没有发生x 存储和 y 存储之间的 before 关系。所以断言 z.load()!=0 可以触发。

关于c++ - std::memory_order_seq_cst 是如何工作的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48963559/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com