在 thread.join() 之后,调用线程是否会看到对局部变量的修改?
Will a calling thread see modifications to local variables after thread.join()?
在最简单的示例中,假设我有一个启动线程的函数,该线程又将局部变量的值设置为 true。我们加入线程,然后离开函数。
bool func() {
bool b = false;
std::thread t([&]() { b = true; });
t.join();
return b;
}
这个函数 return 是否为真,或者行为是否未定义?
是的,它必须 return 正确。
[thread.thread.member]
void join();
4 Effects: Blocks until the thread represented by *this
has completed.
5 Synchronization: The completion of the thread represented by *this
synchronizes with ([intro.multithread]) the corresponding successful join()
return.
因此由句柄表示的线程的执行以及相关的副作用在 join
return 秒到调用上下文之前完成。
例子
让我们看看两个函数,它们的区别仅在于它们加入线程的时间:
int count_A() {
int counter = 0;
bool flag(true);
auto t = std::thread([&]{flag = false;});
while(flag) { // infinite loop - flag never synchronized
++counter;
}
t.join(); // joins thread after loop exits
return counter;
}
int count_B() {
int counter = 0;
bool flag(true);
auto t = std::thread([&]{flag = false;});
t.join(); // joins thread before loop, forcing synchronization
while(flag) {
++counter;
}
return counter;
}
在 -O3
优化下使用 g++ 8.2 版编译时,调用 count_A
会导致无限循环,因为编译器假定 flag
始终为真。
另一方面,调用 count_B
只会 return 值 0
。因为 flag
的值在 thread.join()
之后被检查,它的值被重新加载,并且标志是 false
所以 while 循环不执行。
请注意,如果 flag
更改为 atomic_bool
,则 count_A
具有递增计数器的预期行为,直到标志设置为 false,并且函数 不会进入无限循环(而是returning一旦flag
被子线程设置为false)。
在最简单的示例中,假设我有一个启动线程的函数,该线程又将局部变量的值设置为 true。我们加入线程,然后离开函数。
bool func() {
bool b = false;
std::thread t([&]() { b = true; });
t.join();
return b;
}
这个函数 return 是否为真,或者行为是否未定义?
是的,它必须 return 正确。
[thread.thread.member]
void join();
4 Effects: Blocks until the thread represented by
*this
has completed.5 Synchronization: The completion of the thread represented by
*this
synchronizes with ([intro.multithread]) the corresponding successfuljoin()
return.
因此由句柄表示的线程的执行以及相关的副作用在 join
return 秒到调用上下文之前完成。
例子
让我们看看两个函数,它们的区别仅在于它们加入线程的时间:
int count_A() {
int counter = 0;
bool flag(true);
auto t = std::thread([&]{flag = false;});
while(flag) { // infinite loop - flag never synchronized
++counter;
}
t.join(); // joins thread after loop exits
return counter;
}
int count_B() {
int counter = 0;
bool flag(true);
auto t = std::thread([&]{flag = false;});
t.join(); // joins thread before loop, forcing synchronization
while(flag) {
++counter;
}
return counter;
}
在 -O3
优化下使用 g++ 8.2 版编译时,调用 count_A
会导致无限循环,因为编译器假定 flag
始终为真。
另一方面,调用 count_B
只会 return 值 0
。因为 flag
的值在 thread.join()
之后被检查,它的值被重新加载,并且标志是 false
所以 while 循环不执行。
请注意,如果 flag
更改为 atomic_bool
,则 count_A
具有递增计数器的预期行为,直到标志设置为 false,并且函数 不会进入无限循环(而是returning一旦flag
被子线程设置为false)。