C++ 14(別名C++ 1y)に含めることを提案しているのは、新しいスレッド同期プリミティブです。ラッチとバリアです。提案はN3600の `latch`サンプルに競合状態がありますか?
それは良いアイデアのように聞こえるとサンプルは、それは非常にプログラマフレンドリーに見えるようです。残念ながら、私はサンプルコードは未定義の動作を呼び出すと思います。提案は、latch::~latch()
について:
ラッチを破棄します。他のスレッドが
wait()
にあるときにラッチが破棄された場合、またはcount_down()
が呼び出されている場合、その動作は未定義です。それは「wait()
に」と言うとないことを
注count_down()
用途の説明として、「wait()
にブロックされました」。
は、その後、次のサンプルが提供される:
第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つ以上がまだ待つことを開始していないので、破壊されたラッチをwait()
を呼ぶ可能性が表示されます。
更新:現在、新しいバージョンの提案がありますが、代表例は変更されていません。
@stefan:私は、「ブロックされたスレッドのリリースは」「() 'これらのスレッドを実行するのを待つ少なくとも待機'から復帰まで」 –
はさらに、それが可能だ含まれていることはないと思うことの一つスレッドはまだ 'start_latch.wait()'呼び出しに達していません。 –
私はあなたに同意します。例が壊れているようです... – yohjp