3

cond_var.notify_one()Boost スレッドを使用する単一のプロデューサー/単一のコンシューマー アプリケーションで、コンシューマー スレッドが を呼び出す前に、プロデューサー スレッドが を複数回呼び出すとどうなりcond_var.wait(lock)ますか?

への各呼び出しが呼び出しと 1 対 1 で対応するように、追加の呼び出しをnotify_oneスタックしますか?.wait().notify_one()

編集同時キューを実装するための一般的に引用される例には、次のメソッドがあります。

void push(Data const& data)
{
    boost::mutex::scoped_lock lock(the_mutex);
    the_queue.push(data);
    lock.unlock();
    the_condition_variable.notify_one();
}

void wait_and_pop(Data& popped_value)
{
    boost::mutex::scoped_lock lock(the_mutex);
    while(the_queue.empty())
    {
        the_condition_variable.wait(lock);
    }

    popped_value=the_queue.front();
    the_queue.pop();
}

私はいくつかの非常によく似たコードを使用しましたが、奇妙なメモリの増加を経験しました。これは、消費者スレッドが毎回起動しないことによって説明されるようです.notify_one()(まだ他の作業で忙しいため)。原因。

コンシューマー スレッドがプロデューサー スレッドに追いつかない場合、このコードをスタックしないと失敗するように思われます。私の理論が正しければ、このコードを修正する方法についての提案をいただければ幸いです。

4

2 に答える 2

7

の仕様notify_oneは次のとおりです。

C ++ 11 30.5.1/7:効果:待機中のスレッドがブロックされている場合は*this、それらのスレッドの1つをブロック解除します。

したがって、答えはノーです。現在待機しているスレッドへの呼び出しとnotify_oneウェイクnotify_allアップのみが行われ、後で記憶されることはありません。

更新:申し訳ありませんが、質問をと誤解しましたstd::condition_variable。当然のことながら、Boostの仕様はほぼ同じです。

またはの呼び出しで待機しているスレッドが現在ブロックされている場合は、それらのスレッドの1つをブロック解除します。*thiswaittimed_wait

編集について:誰かが呼び出したときに待機しているスレッドがない場合push、次に呼び出すスレッドは空にならないpopため、まったく待機しません。the_queueしたがって、条件変数が待機してはならないことを覚えておく必要はありません。その情報は、条件変数ではなく、管理されている状態で保存されます。消費者が生産者に追いつけない場合は、消費をスピードアップするか、生産を遅くする必要があります。それを支援するためにシグナリングメカニズムにできることは何もありません。

于 2013-01-29T12:15:14.733 に答える
3

つまり、スタックしません。

notify_one()別のスレッドがを待機している場合にのみ効果がありcond_varます。したがって、消費者が待っていた場合、最初notify_one()の消費者はブロックを解除しました。2番目notify_one()のスレッドは待機していないため、効果はありません。condition_variable

于 2013-01-29T12:15:24.527 に答える