与非原子变量的障碍和同步点 - 数据竞争?

Vit*_*meo 6 c++ concurrency multithreading language-lawyer barrier

考虑以下程序:

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();
}
Run Code Online (Sandbox Code Playgroud)

这个程序是否保证打印出来2,即使i它不是原子变量?

根据cppreference:

调用arrive_and_wait与屏障完成阶段的开始同步.完成阶段的完成与呼叫的返回同步.

呼叫arrive_and_drop并且arrive_and_wait永远不会与他们自己或彼此引入数据竞赛.

这表明每次arrive_and_wait调用都有一个同步点.但是我不确定是否允许编译器重新排序读/写操作i,因为它是非原子的.

bar*_*top 3

据我从std::barrier 参考(我的重点)的理解:

屏障具有完成阶段,一旦参与线程集中的所有线程都到达同步点,该阶段就由参与线程之一执行。到达_and_wait和到达_and_drop调用与完成阶段的开始同步;完成阶段的结束与被其完成阻止的所有调用的返回同步

您可以假设不同线程中的屏障之前所做的所有更改在其他线程中都是可见的,即使它们不是原子的。正如该参考文献所指出的(我的重点):

在线程之间,如果满足以下任一条件,则评估 A 线程间发生在评估 B 之前

1) A 与 B 同步

2) A 按依赖顺序排列在 B 之前

3) A 与某些评估 X 同步,并且 X 在 B 之前排序

4) A 在某些评估 X 之前排序,并且 X 线程间发生在 B 之前

5)A线程间发生在某些评估X之前,并且X线程间发生在B之前