2017-08-07 2 views
-2

私は主な機能ではなく、スレッドを使用する私のコードに関数を持っています。プログラムが実行されると、何千回も呼ばれます。これは、このC++ 11関数は、結合されたスレッドがまだ終了していないときに戻ることができますか?

void my_function(vector<string> input, vector<string> &results) 
{ 
    results.clear(); 
    results.resize(input.size()); 
    vector<thread> th; 

    th.resize(input.size()); 


    for(int i=0; i<input.size();i++) 
    { 
     th[i]=thread(fold, input,ref(results), i); 
    } 

    for(auto & t : th) 
    { 
     t.join(); 
    } 
}  

fold機能コピーoutputのエントリからi inputのエントリiから導出される文字列、のように見えます。 my_functionがすべてのスレッドが終了したときに、スレッドが終了することを確認したい。私はこの質問をする理由は、この関数を並列化した後、私は巨大なメモリリークを起こし、スレッドがリソースを保持していると疑うことです。

+2

はい返すためには、すべてのスレッド関数が返されている必要があります。 'my_function'が返る前にすべての' join'コールが返されなければなりません。 'std :: thread'オブジェクトに関連するすべてのリソースは、対応する' join'呼び出しによって、またはオブジェクトが破壊されたときに( 'my_function'から返ってくる一部として)解放されます。 ***しかしながら***スレッド関数が解放しないリソースを明示的に割り当てる場合、それらは自動的にはクリーンアップされません。 –

+0

@Rezaまた、 'results'を並列アクセスから保護する必要があります。この問題を回避するには、結果のサイズ変更も行う必要があります。各スレッドは番号を知っている必要があります。したがって、割り当てられた変数だけが変更されます。各スレッドが1つの結果文字列を生成すると仮定します。 – Arkady

+0

MCVE折り目は何をするのですか? – SergeyA

答えて

0

あなたの関数は並列化に適していません。各スレッドに、最初にクリアされた同じベクタへの参照ラッパーを与えています。関数foldresultsのサイズ変更/再割り当てを行った場合、一方のスレッドはデータを再割り当てし、新しく割り当てられた領域で動作し、他のスレッドは古い、削除された領域にアクセスしようとします。別の可能性は、複数のスレッドが同時にベクトルのサイズを変更しようとするため、複数の再割り当てとリークが発生することです。

一般的に、複数のスレッドが同時に同じデータを自由に変更できるようにするには、非常にという悪い考えがあります。何が起こるかわからないからです。スレッドのそれぞれが、要素を並べ替え、追加、削除することなく、ベクトル内の独自の要素を変更できるようにします。しかし、その時点で、スレッドが参照する文字列には、それらを含むベクトルではなく、変更する個々の文字列への参照を渡す必要があります。

+0

修正しました。申し訳ありません。 – Reza

+0

理解しやすいマルチスレッドは難しいです。 – jwilson

関連する問題