2016-08-02 8 views
0

私は、C++ STLと並列処理の経験が少ないと言うことから始めます。それでも私の研究をしています...複数の非同期の将来の結果を処理する

私のアプリケーションには大きな傾向があります。私は非同期のfutureを使って、これらのタスクをアラカルトで処理します(より良い用語が不足しているため)。作成される最大タスクは、使用可能なコアの数に基づいています。

私はfutureをクラスメンバvectorに保存して、タスクが呼び出されたメソッドのスコープにバインドされないようにします。それ以外は、タスクが完了した後に結果を処理するという問題があります。ここに私のコードのサンプルは私の質問にコンテキストを提供することです:

if (ALI::WorkingTasks < CPU_HW_CONCURRENCY) { 
    std::string Task = TaskQueue.front(); 
    TaskQueue.pop(); 

    ALI::WorkingTasks++; 
    ALI::AsyncTasks.push_back(std::async(std::launch::async, &ALI::ProcessCodecUI, this, Task)); 
} 

私のクラス定義でstd::async

bool ALI::ProcessCodecUI(std::string UIPath) 
{ 
    // long inefficient process here 

    ALI::WorkingTasks--; 
    // notify condition_variable to create more tasks here 
} 

から呼び出されるメソッドを、これはどのように定義されるかALI::AsyncTasksです。

これはアプリケーションを非常に最小限にするための私の最初の実装です。動作します。私はスレッドプールでいくつかの読書をして、 "アラカルト"スレッドプールの独自の実装を作成するアイデアを突きつけました。

私の質問は次のとおりです。ALI::AsyncTasksの結果をどうすれば処理できますか?すべての例では、futureを直接呼び出して、それを呼び出すメソッドを扱っています。私のシナリオでは、vectorは蓄積し続け、タスクが完了した後でもfutureは決して破壊されません。これはメモリリークを引き起こします。私はとにかくProcessCodeUI()が完了した後にfutureを自己破壊する必要はありません。

明確でない場合は、私にお知らせください。私は改訂します。

はあなたが完了するための非同期操作を待っている間にブロックしたいプログラム内の特定のポイントを持っていない場合は、今後は使用しないでください、あなたに

答えて

0

ありがとうございます。

std :: asyncの代わりにstd::threadを使用し、次にスレッドを即座にdetachingに変更することで、最小限の変更で達成しようとしていることを達成できます。

if (ALI::WorkingTasks < CPU_HW_CONCURRENCY) { 
    std::string Task = TaskQueue.front(); 
    TaskQueue.pop(); 

    ALI::WorkingTasks++; 
    std::thread Thread (&ALI::ProcessCodecUI, this, Task); 
    Thread.detach(); 
} 

スレッドが終了したときにクリーンアップする必要はありません。共通のキューから取得したコアごとにスレッドを生成するほうが効率的ですが、

+1

私はこのルートを検討しましたが、タスクを実行する必要があるときはいつでも新しいスレッドを作成することは非常に高価になることを読んでいます。それで、なぜ私は 'future'を使う道を進んだのですか? – user0000001

+0

std:asyncが実行ごとに新しいスレッドを割り当てないという保証はありませんが、おそらくすべての一般的な実装で正しいと思います。私はコアごとにスレッドを生成し、次に待ち行列から引き出すべきだと思います。複雑ではありません。私はそれが先物を浄化しようとするよりも簡単だと思います。 – nate

関連する問題