【发布时间】:2019-04-22 19:35:57
【问题描述】:
考虑以下程序:
int i{0};
std::experimental::barrier b{2};
int main()
{
std::thread t0{[] {
b.arrive_and_wait();
std::cout << i << '\n';
}};
std::thread t1{[] {
i = 2;
b.arrive_and_wait();
}};
t0.join();
t1.join();
}
即使i 不是原子变量,该程序是否保证打印出2?
根据cppreference:
对
arrive_and_wait的调用与屏障完成阶段的开始同步。完成阶段的完成与调用的返回同步。对
arrive_and_drop和arrive_and_wait的调用绝不会引入彼此之间或彼此之间的数据竞争。
这表明每个arrive_and_wait 调用都有一个同步点。但是我不确定是否允许编译器重新排序i 上的读/写操作,因为它是非原子的。
【问题讨论】:
-
Bartop 是对的。“对
arrive_and_wait()的调用与调用的返回同步”。这就是你的答案.. 如果 A 与 B 同步,则在 A (i = 2) 头间排序之前的语句发生在 B (cout << i) 之后排序的语句之前。这些陈述是否是原子的无关紧要;这与互斥锁用于在线程之间同步非原子数据的机制完全相同。
标签: c++ multithreading concurrency language-lawyer barrier