Conditon Variables の内部実装を考える
wait 側のユーザーコード
mutex->lock(); while(!some_condition) { condition->wait(mutex); } // ここでお仕事。必要に応じて some_condition 書き換え。 mutex->unlock();
wait が内部でやる事は
- (1) mutex->unlock
- (2) スケジューラーの wait queue へ追加(ブロックする)
- (3) mutex->lock
(1)と(2) はアトミック。
(2) により wait はブロックされる。
notifyAll 側のユーザーコード
mutex->lock();
some_condition = true;
condition->notifyAll();
mutex->unlock();
- 同じ Conditon Variable を待っているスレッドを全て run queue へ移動する。
複数スレッドが wait しているとき
wait している複数のスレッドのうち wait 内部の mutex->lock に成功したスレッドが
- (1) 自分の仕事をし
- (2) 必要であれば条件を更新
- (3) mutex->unlock
このスレッドが処理を終えると、mutex->unlock されるので Conditon Variable を待つ別のスレッドのブロックが解除される。
解除されたときには条件が整っていないかもしれないので、以下のようにユーザー側でもう一度条件をチェックしている。
while(!some_condition) {
condition->wait(mutex);
}
という感じでうまく動きそうだが。抜けがないか心配。wait はキャンセルポイントにもなるというのはまあ将来考えよう。