std::notify_all_at_thread_exit
來自 cppreference.com
在標頭檔案 <condition_variable> 中定義 |
||
void notify_all_at_thread_exit( std::condition_variable& cond, std::unique_lock<std::mutex> lk ); |
(C++11 起) | |
notify_all_at_thread_exit
提供了一種機制,用於通知其他執行緒給定執行緒已完全完成,包括銷燬所有 thread_local 物件。其操作如下:
- 先前獲取的鎖 lk 的所有權被轉移到內部儲存。
- 執行環境被修改,使得當前執行緒退出時,條件變數 cond 會收到通知,如同執行了 lk.unlock();
cond.notify_all();。
隱式呼叫的 lk.unlock() 在銷燬與當前執行緒關聯的所有具有 執行緒區域性儲存期 的物件之後執行。
如果滿足以下任何條件,則行為是未定義的:
- 呼叫執行緒不會鎖定 lk。
- 如果其他執行緒也在等待 cond,則 lk.mutex() 與這些執行緒在 cond 上呼叫的等待函式(
wait
、wait_for 和 wait_until)解鎖的互斥量不同。
目錄 |
[編輯] 注意
可以透過 std::promise 或 std::packaged_task 提供的工具實現類似的效果。
提供的鎖 lk 將一直保持到執行緒退出。一旦呼叫此函式,將不能再有其他執行緒獲取相同的鎖以等待 cond。如果一些執行緒正在等待此條件變數,請確保在持有 lk 的鎖時滿足等待條件,並且在呼叫 notify_all_at_thread_exit
之前不要釋放和重新獲取此鎖,以避免其他執行緒中虛假喚醒造成的混淆。
在典型用例中,此函式是分離執行緒呼叫的最後一項操作。
[編輯] 引數
cond | - | 線上程退出時通知的條件變數 |
lk | - | 與條件變數 cond 關聯的鎖 |
[編輯] 返回值
(無)
[編輯] 示例
此部分程式碼片段說明了如何使用 notify_all_at_thread_exit
來避免線上程區域性變數正在析構時訪問依賴於這些執行緒區域性變數的資料
執行此程式碼
#include <cassert> #include <condition_variable> #include <mutex> #include <string> #include <thread> std::mutex m; std::condition_variable cv; bool ready = false; std::string result; // some arbitrary type void thread_func() { thread_local std::string thread_local_data = "42"; std::unique_lock<std::mutex> lk(m); // assign a value to result using thread_local data result = thread_local_data; ready = true; std::notify_all_at_thread_exit(cv, std::move(lk)); } // 1. destroy thread_locals; // 2. unlock mutex; // 3. notify cv. int main() { std::thread t(thread_func); t.detach(); // do other work // ... // wait for the detached thread std::unique_lock<std::mutex> lk(m); cv.wait(lk, []{ return ready; }); // result is ready and thread_local destructors have finished, no UB assert(result == "42"); }
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
---|---|---|---|
LWG 2140 | C++11 | 呼叫 notify_all_at_thread_exit 與等待 cond 的函式的呼叫同步 |
更新了同步 要求 |
[編輯] 參閱
將結果設定為特定值,僅線上程退出時傳送通知 ( std::promise<R> 的公共成員函式) | |
執行函式,確保僅在當前執行緒退出後結果才就緒 ( std::packaged_task<R(Args...)> 的公共成員函式) |