簡體   English   中英

調用線程是否會在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;
}

這個函數會返回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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM