gpt4 book ai didi

multithreading - 这种释放/获取语义的使用是否包含潜在的数据竞争?

转载 作者:行者123 更新时间:2023-12-04 06:37:56 24 4
gpt4 key购买 nike

考虑以下我在 http://preshing.com/20120913/acquire-and-release-semantics/ 上找到的代码(但我确定我在其他地方经常看到它)

常用代码:

int A = 0;
std::atomic<int> Ready(0);

线程 1 执行的代码:

A = 42
Ready.store(1, std::memory_order_release);

线程 2 执行的代码:

int r1 = Ready.load(std::memory_order_acquire);
int r2 = A;

然后可以说,if r1 == 1 then r2 将始终为 42,并且没有数据竞争。

我的第一个问题是:代码是否包含数据竞争?我的意思是在 r1 == 0 的情况下。例如,线程 1 可以在存储到 A 的中途被抢占,然后线程 2 可以开始执行。

我认为线程 2 的代码应该重写为:

int r1 = Ready.load(std::memory_order_acquire);
int r2 = 0;
if( r1 == 1 ) {
r2 = A;
}

避免潜在的数据竞争。

这是真的吗?

最佳答案

是的,您的解释是正确的:由于无条件读取A,程序包含数据竞争。该程序被简化为一个最小的示例来演示博客的获取-释放的工作原理:作者仅讨论了内存排序如何强制“读取器”线程必须 中读取 42 A 如果它从 Ready 读取 1。他没有谈论替代方案,因为它不是 germaine。

在实际程序中,“阅读器”线程可能会在循环中等待 Ready 以获得所需的语义:

int A = 0;
std::atomic<int> Ready(0);

void write_thread() {
A = 42;
Ready.store(1, std::memory_order_release);
}

void read_thread() {
while (!Ready.load(std::memory_order_acquire))
;
int r2 = A;
assert(r2 == 42);
}

或者在您的示例中使用条件:

int A = 0;
std::atomic<int> Ready(0);

void write_thread() {
A = 42;
Ready.store(1, std::memory_order_release);
}

void read_thread() {
while (true) {
if (Ready.load(std::memory_order_acquire)) {
int r2 = A;
assert(r2 == 42);
break;
}

std::cout << "Not ready yet - try again later.\n" << std:flush;
std::this_thread::sleep_for(std::chrono::milliseconds{125});
}
}

关于multithreading - 这种释放/获取语义的使用是否包含潜在的数据竞争?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22118329/

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