2016-08-02 11 views
0

一連のパラメータを異なるC++スレッドに渡そうとしています。プログラムはNumThreads == 1のときに正常に動作しますが、NumThreads> 1のときは、関数に渡すpパラメータがスレッド内で正しくありません。私はスレッドのコンストラクタで何かを見逃して、値でpを渡していませんか?C++マルチスレッドの引数の問題

int NumThreads = 2; 
std::thread t[numSamplePoints]; 
std::mutex dataLock; 

for(int i = 0 ; i < numSamplePoints ; i++) 
{ 
    // Prevent more than NumThreads from running at once 
    if(i > NumThreads && t[i-NumThreads].joinable()) 
    { 
    t[i - this->NumThreads].join(); 
    } 

    // Set and Check Input Parameters 
    double p[3]; 
    srcPoints->GetPoint(i , p); 
    if(i < 3) 
    { 
    cout<< "OUTTHREAD " << p[0] << " " << p[1] << " " << p[2] <<endl; 
    cout<< "src: " << Id << " index: " << i <<endl; 
    } 

    t[i] = std::thread(&MyClass::MyFunction, this, &dataLock, i, Id, p); 
} 

とメンバ関数が呼び出される:スレッドが作成され

void MyClass::MyFunction(std::mutex *dataLock, int sampleIndex, int Id, double srcPoint[3]) 
{ 
    dataLock->lock(); 
    if(sampleIndex < 3) 
    { 
    cout<< "IN THREAD " << srcPoint[0] << " " << srcPoint[1] << " " << srcPoint[2] <<endl; 
    cout<< "src: " << sourceId << " index: " << sampleIndex <<endl; 
    } 
    dataLock->unlock(); 
} 

最初の3つのスレッドからのコンソール出力:だから {

OUTTHREAD 45.7694 1.06209 -60.9628 
src: 0 index: 0 
OUTTHREAD 48.6044 -5.40514 -54.7663 
src: 108 index: 1 
OUTTHREAD 52.505 9.00298 -47.0499 
src: 216 index: 2 

IN THREAD 52.505 9.00298 -47.0499 
src: 0 index: 0 
IN THREAD 52.505 9.00298 -47.0499 
src: 108 index: 1 
IN THREAD 52.505 9.00298 -47.0499 
src: 216 index: 2 

IDとサンプルインデックスがスレッドに正しく渡されていますが、どのようにsrcPoint 3つのスレッドすべてで同じですか?

+2

すべてのスレッドに同じ 'p'配列を渡しているので、スレッドがそれらを読み込む前に値を変更することになります。 –

+0

@MattTimmermans 'p'は本当に同じですか? forループの繰り返しごとに新たに割り当てられますか、何か逃しましたか? @JjBannister私たちは 'srcPoints'が何であるか分からず、GetPoints(int、double [])関数が何をするのか分かりません。多分それはちょうど正しい動作です。 – Mael

+0

私は@ MAELに同意しています。それはあなたがそれが行動することを期待している方法で_正しい行動_かもしれません。レースの条件はマットが指摘しているように面白いです。 – M4rc

答えて

1

ローカル変数へのポインタをスレッドに渡し、変数が使用される前にスコープから外れるようにすることで、未定義の動作を呼び出しています。

Cスタイルの配列は決して値渡されません。引数が実際にポインタをとるよう配列型を取るように宣言された関数:

void MyClass::MyFunction(std::mutex *dataLock, int sampleIndex, int Id, double srcPoint[3]) 

は、この場合、

void MyClass::MyFunction(std::mutex *dataLock, int sampleIndex, int Id, double* srcPoint) 

と同等ですが、あなたのp配列は、あなたのforループ範囲にローカルであり、それthreadコンストラクタに渡されるときに暗黙的にその最初の要素へのポインタに減衰します。ループの各繰り返しが完了すると、pは有効範囲外になり破棄されますが、スレッドには使用されていたメモリへのポインタが残っています。

この問題を修正するための最良のオプションは、あなたのループでstd::array<double, 3> pdouble p[3]を交換するとMyClass::MyFunctionではなくdouble srcPoint[3]のパラメータstd::array<double, 3> srcPointを取る作ることであろう。生のCスタイルの配列とは異なり、std::arrayは値渡し可能で、期待するコピーセマンティクスを実装します。

+0

これはそれでした。ありがとうございました!! –

関連する問題