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 関係を持ちます (std::memory_order を参照してください)。
std::promise または std::packaged_task によって提供される機能を使用しても同等の効果を得ることができます。
ノート
lock.mutex() が現在のスレッドによってロックされていない場合、この関数の呼び出しは未定義動作です。
lock.mutex() が同じ条件変数で現在待機している他のすべてのスレッドが使用しているミューテックスと同じでない場合、この関数の呼び出しは未定義動作です。
指定されたロック lk はスレッドが終了するまで保持されます。 いったんこの関数が呼ばれると、いかなるスレッドも cond で待機するために同じロックを取得することはできません。 この条件変数で待機中のスレッドがある場合、そのスレッドは spurious wakeup したときにロックの解放と再取得を試みるべきではありません。
一般的なユースケースでは、この関数はデタッチされたスレッドによって呼ばれる最後の関数になります。
引数
| cond | - | スレッド終了時に通知するための条件変数 |
| lk | - | 条件変数 cond に紐付けられているロック
|
戻り値
(なし)
例
この部分的なコード片は、スレッドローカルが破棄処理を行なっている間、それに依存するデータへのアクセスを回避するために、どのように notify_all_at_thread_exit を使用できるかを示します。
#include <mutex>
#include <thread>
#include <condition_variable>
#include <cassert>
#include <string>
std::mutex m;
std::condition_variable cv;
bool ready = false;
std::string result; // 何らかの適当な型。
void thread_func()
{
thread_local std::string thread_local_data = "42";
std::unique_lock<std::mutex> lk(m);
// thread_local なデータを用いて result に値を代入します。
result = thread_local_data;
ready = true;
std::notify_all_at_thread_exit(cv, std::move(lk));
} // 1. thread_local が破棄されます。
// 2. mutex のロックが解除されます。
// 3. cv が通知されます。
int main()
{
std::thread t(thread_func);
t.detach();
// 他の処理をします。
// ...
// デタッチしたスレッドを待ちます。
std::unique_lock<std::mutex> lk(m);
cv.wait(lk, []{ return ready; });
// result は利用可能で、 thread_local のデストラクタは終了しています。 未定義動作は発生しません。
assert(result == "42");
}
関連項目
| スレッド終了時にのみ通知が配送されるように特定の値に結果を設定します ( std::promise<R>のパブリックメンバ関数)
| |
| 関数を実行し、カレントスレッドの終了後にのみ結果が準備完了になるようにします ( std::packaged_task<R(Args...)>のパブリックメンバ関数)
|