std :: thread :: join是否保证写入可见性 [英] Does std::thread::join guarantee writes visibility
问题描述
据说Std :: thread :: join与所连接的线程同步",但是同步并不能说明副作用的可见性,它仅控制可见性的顺序,即.在以下示例中:
Std::thread::join is said to 'synchronize-with' the joined thread, however synchronization doesnt tell anything about visibility of side effects, it merely governs the order of the visiblity, ie. in following example:
int g_i = 0;
int main()
{
auto fn = [&] {g_i = 1;};
std::thread t1(fn);
t1.join();
return g_i;
}
在c ++标准中我们是否有任何保证,该程序将始终返回1?
Do we have any guarantee in the c++ standard that this program will always return 1?
推荐答案
void join();
效果:阻塞,直到由* this
表示的线程完成.
同步:由* this
表示的线程的完成与相应的成功join()
返回同步.
void join();
Effects: Blocks until the thread represented by*this
has completed.
Synchronization: The completion of the thread represented by*this
synchronizes with the corresponding successfuljoin()
return.
由于线程执行的完成与 thread :: join
的返回同步,因此线程
Since the completion of the thread execution synchronizes with the return from thread::join
, the completion of the thread inter-thread happens before the return:
如果
,则评估 A 线程间发生在评估 B 之前— A 与 B
An evaluation A inter-thread happens before an evaluation B if
— A synchronizes with B
,因此发生在它之前:>
评估 A 发生在评估 B 之前(或者等效地, B 发生在 A 之后):
— A 线程间发生在 B
An evaluation A happens before an evaluation B (or, equivalently, B happens after A) if:
— A inter-thread happens before B
由于(线程间)发生在可传递性之前(让我跳过复制以粘贴线程间的整个定义发生在显示这一点之前),因此在线程完成之前发生的所有事情,包括值 1
进入 g_i
,发生在从 thread :: join
返回之前.反过来,从 thread :: join
返回的结果发生在读取 return g_i;
中的 g_i
的值之前,仅仅是因为调用了 thread :: join
在 return g_i;
之前排序.再次,使用传递性,我们确定在非主线程中将 1
写入 g_i
的操作发生在读取 g_i
中的在主线程中返回g_i;
.
Due to (inter-thread) happens before transitivity (let me skip copypasting the whole definition of inter-thread happens before to show this), everything what happened before the completion of the thread, including the write of the value 1
into g_i
, happens before the return from thread::join
. The return from thread::join
, in turn, happens before the read of value of g_i
in return g_i;
simply because the invocation of thread::join
is sequenced before return g_i;
. Again, using the transitivity, we establish that the write of 1
to g_i
in the non-main thread happens before the read of g_i
in return g_i;
in the main thread.