ここでは、複数のスレッドから呼び出されるコードがあります。 std::condition_variable::wait
の述語はスレッドごとに少し異なりますが、問題は変わりません。std :: condition_variable :: notify_allの後に複数のスレッドがstd :: unique_lock <std::mutex>をどのように再獲得するかを注文します。
std::unique_lock<std::mutex> lock{connection_mutex};
cv.wait(lock,
[conn = shared_from_this()]
{
return conn->connection_is_made();
}
);
//do some stuff
lock.unlock();
でこれを読んで条件変数を通知し、タイムアウトの期限が切れる、またはスプリアスウェイクアップが発生した場合、スレッドが起こされると、ミューテックスがアトミックに再取得されます。スレッドは、条件をチェックし、起床が偽である場合は待機を再開します。このことから
私は述語ラムダがチェックされ、それがtrue
を返す場合lock
がロックされたままになり、私はこのmutexの保護の下でいくつかのものをし続けることができるよりも、lock
がロックされることを理解しています。 std::condition_variable
がnotify_one()
メンバー機能によって通知されると、それは完璧な意味を持ちます。
std::condition_variable
にnotify_all()
が通知されるとどうなりますか?すべてのスレッドが起動してミューテックスをロックするために "行内で待機"してから、述語が返すものをチェックするか、あるいは何か他のことを行うかどうかを確認するだけで、ドキュメントで見つけることはできません。
EDIT:以下のコメントを見て少し考えました。 std::condition_variable::wait
は、第1引数にstd::unique_lock
があり、通知後にstd::condition_variable::wait
が呼び起こされた場合 - std::unique_lock
が再取得されます。複数のスレッドが同じ通知を待っている場合は、notify_all()
が最後に呼び出されたときよりstd::condition_variable
スレッドは1つのスレッドしかmutexをロックできず、他のすべてのスレッドはスリープ状態に戻ります。だから効率が低い以外はnotify_one()
と同じ効果がある場合は、notify_all()
メンバ関数を持っていても意味がありません。私は、 のスレッドをstd::condition_variable::wait
に戻すためにmutexを再度取得しなければならない場合、待機中のすべてのスレッドが同時にそれを行うことができないことを意味します。
通知の順序について質問している場合、これは役立つ可能性があります。http:// stackoverflow。com/questions/15912322/condition-variable-deadlock – didiz
回答ありがとうございます。この場合、私はnotify_all()シグナルを受け取ることはないと心配していません。私は、同じcondition_variableで待機するときに複数のスレッドがどのように動作するのかを知りたいだけで、notify_all()で通知を受け取り、同じmutexを取得しようとします。 – etrusks
OSスケジューラに任されています。どちらのスレッドが最初にミューテックスを取得するかは分かりません。 – 1000ml