3

この例では、待機中のスレッドの数がウェイクアップします。

1番目のスレッド

void wakeUp2Threads()
{
    std::unique_lock<std::mutex> lock(condvar_mutex);

    condvar.notify_one();
    condvar.notify_one();
}

2番目のスレッド

{
    std::unique_lock<std::mutex> lock(condvar_mutex);

    condvar.wait(lock); <- 2nd thread has entered here before 1st thread entered wakeUp2Threads.
}

3番目のスレッド(2番目と同じ):

{
    std::unique_lock<std::mutex> lock(condvar_mutex);

    condvar.wait(lock); <- 3rd thread has entered here before 1st thread entered wakeUp2Threads.
}

この例では、両方の通知が同じスレッドではなく、異なるスレッドに複数回配信されるという保証はありますか?

つまり、notify_one()の意味は次のとおりです。

1) notify one thread, no matter has it been already notified (but has not been woken up yet), or not. (* see note)
or
2) notify one thread, but only this one, which has not been notified yet.

(*) 注意を払う!ここでは、「待機中のスレッドが過去に通知され、ウェイクアップされ、いくつかの処理を実行して、再びcondvar.wait()に入った」というシナリオについては話していません。もちろん、この場合、いくつかのnotify_one()ルーチンがウェイクアップできます。同じスレッドを何度も繰り返します。

私は別のケースについて話している

notify_one()は待機中のスレッドにウェイクアップについて通知しましたが、この待機中のスレッドがカーネルスケジューラからタイムスロットを受け取り、実行を継続する前に、別のnotify_one()が再度呼び出されました。この2番目の通知が、最初の通知からまだウェイクアップされていないときに、同じスレッドに再度配信される可能性はありますか?

4

1 に答える 1

7

このnotify_one呼び出しは、1つのスレッドのブロックをアトミックに解除します。つまり、2回目に呼び出されたときに、ブロックされなくなったため、同じスレッドのブロックを解除することはできません。

これは、セクション30.5/3および30.5.1/7の標準で指定されています。

于 2013-02-26T09:51:18.443 に答える