[英]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;
}
這個函數會返回true,還是行為未定義?
是的,它必須返回true。
[thread.thread.member]
void join();
4 效果 :阻塞直到由
*this
表示的線程完成。5 同步 :由
*this
表示的線程的完成與([intro.multithread])同步相應的成功join()
返回。
因此,句柄表示的線程的執行以及相關的副作用在join
返回到調用上下文之前完成。
讓我們看看兩個函數,它們只在加入一個線程時有所不同:
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
始終為true。
另一方面,調用count_B
只會返回值0
。 因為在thread.join()
之后檢查了flag
的值,所以重新加載它的值,並且flag為false
因此while循環不會執行。
請注意,如果flag
更改為atomic_bool
,則count_A
具有遞增計數器的預期行為,直到該標志設置為false,並且該函數不會進入無限循環(而是返回一次由子線程將flag
設置為false )。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.