web-dev-qa-db-ja.com

複数の先物を待っていますか?

同じ種類のタスク(ワーカースレッド)を実行したいのですが、一度に特定の数のタスクを実行したくないです。タスクが終了すると、その結果は新しいタスクへの入力になり、そのタスクを開始できます。

これをC++ 11の非同期/将来のパラダイムで実装する良い方法はありますか?

一見、単純に見えます。次のようにして複数のタスクを生成します。

_std::future<T> result = std::async(...);
_

そして、result.get()を実行して、タスクの非同期結果を取得します。

ただし、ここでの問題は、将来のオブジェクトを何らかのキューに格納し、1つずつ待機する必要があることです。ただし、将来のオブジェクトを何度も繰り返して準備ができているかどうかを確認することは可能ですが、不要なCPU負荷のために望ましくありません。

与えられたセットのany futureが準備ができて結果を得るのをどうにかして待つことは可能ですか

私がこれまでのところ考えることができる唯一のオプションは、非同期/将来のない旧式のアプローチです。具体的には、複数のワーカースレッドを生成し、各スレッドの最後に結果をミューテックスで保護されたキューにプッシュして、条件変数を介して待機スレッドに通知します。

非同期/将来の可能性がある他のより良いソリューションはありますか?

43
alveko

C++ 11でのスレッドのサポートは最初のパスであり、std::futureは揺れ動きますが、複数の待機はまだサポートしていません。

ただし、比較的非効率的に偽造できます。最終的に、各std::future(非常に高価な)ごとにヘルパースレッドを作成し、それらの「this future is ready」を同期した多プロデューサーの単一消費者メッセージキューに収集し、セットアップします。指定されたstd::futureの準備ができているという事実をディスパッチするコンシューマータスク。

このシステムのstd::futureは多くの機能を追加しないので、準備が整っていることを直接示し、その結果を上記のキューに入れるタスクを持っている方が効率的です。このルートに進むと、std::asyncまたはstd::threadのパターンに一致するラッパーを作成し、キューメッセージを表すstd::futureのようなオブジェクトを返すことができます。これには基本的に、同時実行ライブラリのチャンクの再実装が含まれます。

std::futureを使い続けたい場合は、shared_futuresを作成し、各依存タスクをshared_futuresのセットに依存させることができます。つまり、中央スケジューラなしで実行します。これは、アボート/シャットダウンメッセージのようなものを許可しません。これは、堅牢なマルチスレッドタスクシステムに不可欠だと思います。

最後に、問題を解決するために、 C++ 2x を待つか、並行処理TSが標準に組み込まれるたびに待つことができます。

generation 1」のすべてのフューチャーを作成し、それらすべてのフューチャーをgeneration 2タスクに渡して、タスクが入力を待つようにすることができます。

6
Sebastian Mach