gpt4 book ai didi

c++ - 发生在同一线程中的关系之前

转载 作者:行者123 更新时间:2023-12-05 03:22:02 24 4
gpt4 key购买 nike

我正在阅读“C++ Concurrency in Action”一书关于 C++ 内存模型的第 5.3 节,下面的 list 5.5 让我感到困惑:

std::atomic<bool> x,y;
std::atomic<int> z;
void write_x_then_y()
{
// Is there a Happens-Before relationship for statement (1) and (2) below?
x.store(true,std::memory_order_relaxed); // --> (1)
y.store(true,std::memory_order_relaxed); // --> (2)
}
void read_y_then_x()
{
while(!y.load(std::memory_order_relaxed));
if(x.load(std::memory_order_relaxed))
++z;
}

int main()
{
x=false;
y=false;
z=0;
std::thread a(write_x_then_y); std::thread b(read_y_then_x);
a.join();
b.join();
assert(z.load()!=0);
}

让我感到困惑的是函数 void write_x_then_y()。作者说“这次 main() 末尾的断言可以触发”并且原子变量 x 上的语句 (1) 与关于原子变量 y 的语句 (2)。但我认为对于 std::memory_order_relaxed不同 原子变量之间没有同步,编译器/CPU 可以在不违反程序语义的情况下重新排序这两个语句。

The happensbeforerelationships from listing 5.5 are shown in figure 5.4, along with a possible outcome.enter image description here

最佳答案

一个评估先于另一个评估也发生在它之前。

Sequenced-before 是同一线程中的评估之间的关系,并且独立于同步机制,例如具有非松弛内存顺序的原子加载/存储。

Happens-before 只是通过合并线程间的同步机制将评估顺序的sequenced-before 关系从单线程情况扩展到多线程情况。

参见 https://en.cppreference.com/w/cpp/atomic/memory_order以获得确切的定义。

在另一个语句之前的一个语句中的求值总是先于后者。 (基本上在两个语句之间有一个序列点,尽管自 C++11 以来不再使用该术语。)


编译器可以重新排序这两个松散存储。不过,这并不影响happens-before 关系。仅仅因为两个存储(在不同的原子上)先于彼此并不意味着存储不能被另一个线程以不同的顺序观察,如图中的示例所示。

您需要在加载和存储之间建立先发生 关系,以防止出现所示结果。并且需要以某种方式进行线程间排序,例如通过释放/获取原子操作。基本上,您需要在图中的灰色框之间建立一些箭头。

关于c++ - 发生在同一线程中的关系之前,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72843313/

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