2

ブースト ライブラリ (C++11 標準より前) は、スレッドのサポートを提供しました。サポートの一環として、同期を可能にする単純なクラスである「バリア」の実装も提供します。ブーストのウェブサイトを引用するには:

「バリアは単純な概念です。ランデブーとも呼ばれ、複数のスレッド間の同期ポイントです。バリアは、特定の数のスレッド (n) に対して構成され、スレッドがバリアに到達すると、n 個のスレッドすべてが待機する必要があります。 n 番目のスレッドがバリアに到達すると、待機中のすべてのスレッドが処理を続行できるようになり、バリアがリセットされます。」

Boost 1.54 の時点でのバリア (待機) のメイン関数の実装を以下に示します。

bool wait()
{
    boost::mutex::scoped_lock lock(m_mutex);
    unsigned int gen = m_generation;

    if (--m_count == 0)
    {
        m_generation++;
        m_count = m_threshold;
        m_cond.notify_all();
        return true;
    }

    while (gen == m_generation)
        m_cond.wait(lock);
    return false;
}

バリアは再利用可能であることがわかります。一度構築すると、最初の使用後に破壊する必要はありません。

私の質問は次のとおりです。変数 m_ge​​neration は何のためのものですか? ブーストライブラリの作成者には、それを含める理由があったと思います。バリアがリセットされる/再利用できるようになるたびにインクリメントされますが、その目的は何ですか? プライベート変数なので、外部から読み出せません。同じ問題は、プライベート クラス変数を使用せずに、wait() 関数内の単純な内部 bool 変数を使用して簡単に解決できます。

4

1 に答える 1

5

簡単に言えば、偽の wakeupm_generationに対処するために必要です。

生成カウンターは条件変数と組み合わせて使用​​され、バリアで待機しているすべてのスレッドに自由に続行できることを通知します。

  • バリアに到達したスレッドがm_thresholdあると、その世代番号が増加し、条件変数が通知されます。これにより、待機中のスレッド (つまり、以前にバリアに到達したスレッド) が からウェイクアップしm_cond.wait(lock)ます。

  • 現在、待機中のスレッドは他の理由m_cond.wait(lock)でウェイクアップできます。ここで出番です。変更された場合、バリアはリセットされ、スレッドは続行できます。それでも同じ値が含まれている場合、スレッドは に戻る必要があります。m_generationm_generationm_cond.wait(lock)

wait()各スレッドには独自のインスタンスがあるため、自動変数を内部に持つことはこれを達成しません。

于 2014-10-04T08:07:14.313 に答える