2016-04-15 14 views
0

私はstd::asyncを使用して、以前に逐次実行されていたタスクの実行を高速化しました。std :: asyncタスクの完了を通知する

私の実装は、以下のない:

  1. (例えば、最大で10個の同時タスクの)タスクの事前設定された番号を起動し、これらのタスクのための先物は、ベクターに格納されています。
  2. 1つのタスクが終了するとすぐに別のタスクを起動するため、任意の時点で最大10個のタスク(この値が設定されている)が実行されます。
  3. 10個のタスクを起動した後、実装は、その先のget()を呼び出すことで、最も古いタスク(つまり、ベクトルの最初のタスク)が完了するのを待ちます。

これは正常に動作しますが、10個のタスクのいずれかが最初に完了する可能性があります。私の実装は、常にベクトルの最初のタスクを待ちます。知っている方法はありますか?最初に完了した10のタスクはどれですか?

将来のオブジェクト自体は準備ができていることを通知します。 https://msdn.microsoft.com/en-us/library/jj155756.aspx

+0

おそらく二重引用符:http://stackoverflow.com/questions/27341029/what-is-the-best-way-to-wait-on-multiple-condition-variables-in-c11 –

+0

コードを表示してください。これを行う方法はたくさんあります。 – Tyler

+0

答えをありがとう。私は質問に詳細を追加します。 –

答えて

1

私はWhenAny(C#)がC++ 11/14標準にまだ組み込まれていないと考えて、実験的な将来の拡張として考えています(this参照)。 最新バージョンのBoostライブラリには、when_any、check thisが含まれていると思います。 このcompanyは、when_anyを含む完全なスレッドライブラリも販売しています。

1

は彼らに各IDを与え、終了その最初を保存するために、原子を使用します。

私はこの資料に記載さ「WhenAny()」機能と同様の機能を実現したいです。それは一度だけ実行される

first_id.compare_exchange_strong(0, id); 

idは1〜10であり、第一各タスクの完了時に

std::atomic<int> first_id(0); 

機能の全ての範囲のどこかこれを実行するものが0に置き換わるものになります。

編集:上記はあなたの文字通りの質問に対する答えです。しかし、それは本当にあなたが望むことをするのに役立ちません。あなたが望むことをするために、私はベクトルをキューに変更し、終了時に各タスクを次のキューにエンキューします(変更する前にキューをロックするロックが必要です)。 (恥知らずのプラグ:here's mine)スレッドプールではすべてのタスクをエンキューできますが、nスレッドしか使用できません。これによりスケジューラの過負荷が回避され、コーディングが簡単になります。

1

スレッドプールを使用します。すべてのタスクをキューに入れます。完了したら原子カウンターに報告し、カウンターがすべて完了したと言ったら条件変数を知らせるようにしてください。

スレッドプールの実装には、スタックオーバーフローやその他のものがたくさんあります。

クライアントコードで直接C++ 11スレッディングプリミティブを使用するのは疑わしいです。小さなヘルパーを書くためにそれらを使用する方が良い考えです。

関連する問題