6

C++14 (別名 C++1y) に含めることが提案されているのは、いくつかの新しいスレッド同期プリミティブ (ラッチとバリア) です。提案は

良いアイデアのように思えますし、サンプルを見ると非常にプログラマーフレンドリーに見えます。残念ながら、サンプル コードは未定義の動作を呼び出すと思います。提案は次のように述べていlatch::~latch()ます:

ラッチを破棄します。他のスレッドが にあるwait()、または呼び出している間にラッチが破棄された場合count_down()、動作は未定義です。

使用の説明として、wait()「ブロックされている」ではなく「で」と表示されていることに注意してください。wait()count_down()

次に、次のサンプルが提供されます。

2 番目のユースケースの例を以下に示します。データをロードしてから、多数のスレッドを使用して処理する必要があります。データのロードは I/O バウンドですが、スレッドの開始とデータ構造の作成は CPU バウンドです。これらを並行して実行することで、スループットを向上させることができます。

void DoWork()
{
    latch start_latch(1);
    vector<thread*> workers;
    for (int i = 0; i < NTHREADS; ++i) {
      workers.push_back(new thread([&] {
        // Initialize data structures. This is CPU bound.
        ...
        start_latch.wait();
        // perform work
        ...
      }));
    }
    // Load input data. This is I/O bound.
    ...
    // Threads can now start processing
    start_latch.count_down();
}

wait()スレッドのウェイクアップと からの復帰、およびスコープを離れるときのラッチの破壊との間に競合状態はありませんか? それに加えて、すべてのthreadオブジェクトがリークされます。count_downスケジューラが返される前にすべてのワーカー スレッドを実行せず、start_latchオブジェクトがスコープを離れる場合、未定義の動作が発生すると思います。おそらく、修正はベクトルとjoin()すべてdeleteのワーカースレッドを繰り返してcount_downから返すことです。

  1. サンプルコードに問題はありますか?
  2. レビュアーが使用体験がどのようなものになるかを確認するために、タスクが非常に単純であっても、提案は完全に正しい例を示すべきであることに同意しますか?

注: 1 つ以上のワーカー スレッドがまだ待機を開始していない可能性があるためwait()、破棄されたラッチを呼び出します。


更新: 現在、提案の新しいバージョンがありますが、代表的な例は変更されていません。

4

1 に答える 1