std::thread::join 是否保证写入可见性

Sal*_*r86 6 c++ multithreading language-lawyer

据说 Std::thread::join 与加入的线程“同步”,但是同步并没有说明任何关于副作用的可见性,它只是控制可见性的顺序,即。在以下示例中:

int g_i = 0;
int main()
{
  auto fn = [&] {g_i = 1;};
  std::thread t1(fn);
  t1.join();
  return g_i;
}
Run Code Online (Sandbox Code Playgroud)

我们是否在 C++ 标准中保证该程序将始终返回 1?

Lan*_*yer 9

[线程.线程.成员]

void join();
效果:阻塞直到由 表示的线程*this完成。
同步:表示的线程完成*this与对应的成功join()返回同步。

由于线程执行的完成与从 的返回同步thread::join,因此线程间线程的完成发生在返回之前

评价一个线程间的评估之前发生如果
-一个与同步

因此发生在之前

评价的评价之前发生(或,等价地,后会发生),如果:
-线程间之前发生

由于(线程间)发生在传递性之前(让我跳过复制粘贴整个线程间的定义发生在此之前以显示这一点),线程完成之前发生的所有事情,包括将值1写入g_i,都发生在从thread::join. thread::join反过来,从 的返回发生在读取g_iin的值之前,return g_i;因为 的调用在thread::join之前进行return g_i;。同样,使用传递性,我们确定非主线程中1to的写入g_i发生在主线程g_ireturn g_i;in 的读取之前。

1g_i可见的副作用相对的读取g_ireturn g_i;

甲可见副作用上的标量对象或位字段中号相对于一个值计算中号满足条件:
-之前发生
-没有其它副作用X中号,使得之前发生XX发生在B之前。由评估B确定
的非原子标量对象或位域M的值应为可见副作用A存储的值。

最后一句的重点是我的,它保证从g_iin读取的值return g_i;将是1