std:: notify_all_at_thread_exit
|
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
ヘッダーで定義
<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 ( ) は、現在のスレッドに関連付けられた sequenced after すべての thread local storage duration を持つオブジェクトの破棄の後に順序付けられます。
以下のいずれかの条件が満たされる場合、動作は未定義です:
- 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++規格に対して遡及的に適用されました。
| DR | 適用対象 | 公開時の動作 | 正しい動作 |
|---|---|---|---|
| LWG 2140 | C++11 |
notify_all_at_thread_exit
の呼び出しは
cond で待機する関数の呼び出しと同期する |
同期要件を更新
|
関連項目
|
スレッド終了時のみ通知を配信しながら結果を特定の値に設定する
(
std::promise<R>
の公開メンバ関数)
|
|
|
現在のスレッドが終了した時点でのみ結果が準備完了となるように関数を実行する
(
std::packaged_task<R(Args...)>
の公開メンバ関数)
|