非原子变量的障碍和同步点 - 数据竞争?
Barriers and synchronization points with non-atomic variables - data race?
考虑以下程序:
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:
Calls to arrive_and_wait
synchronizes with the start of the completion phase of the barrier. The completion of the completion phase synchronizes with the return from the call.
Calls to arrive_and_drop
and arrive_and_wait
never introduce data races with themselves or each other.
这表明每个 arrive_and_wait
调用都有一个同步点。但是我不确定是否允许编译器对 i
上的 read/write 操作重新排序,因为它是非原子的。
据我了解std::barrier reference(重点):
A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.
您可以假设在不同线程中的屏障之前所做的所有更改在其他线程中都是可见的,即使它们不是非原子的。正如 this reference 指出的(我的重点):
Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true
1) A synchronizes-with B
2) A is dependency-ordered before B
3) A synchronizes-with some evaluation X, and X is sequenced-before B
4) A is sequenced-before some evaluation X, and X inter-thread happens-before B
5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B
考虑以下程序:
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:
Calls to
arrive_and_wait
synchronizes with the start of the completion phase of the barrier. The completion of the completion phase synchronizes with the return from the call.Calls to
arrive_and_drop
andarrive_and_wait
never introduce data races with themselves or each other.
这表明每个 arrive_and_wait
调用都有一个同步点。但是我不确定是否允许编译器对 i
上的 read/write 操作重新排序,因为它是非原子的。
据我了解std::barrier reference(重点):
A barrier has a completion phase, which is executed by one of the participating threads once all threads in the set of participating threads arrive at the synchronization point. The arrive_and_wait and arrive_and_drop calls synchronize with the start of the completion phase; the end of the completion phase synchronizes with the returns from all calls blocked by its completion.
您可以假设在不同线程中的屏障之前所做的所有更改在其他线程中都是可见的,即使它们不是非原子的。正如 this reference 指出的(我的重点):
Between threads, evaluation A inter-thread happens before evaluation B if any of the following is true
1) A synchronizes-with B
2) A is dependency-ordered before B
3) A synchronizes-with some evaluation X, and X is sequenced-before B
4) A is sequenced-before some evaluation X, and X inter-thread happens-before B
5) A inter-thread happens-before some evaluation X, and X inter-thread happens-before B