2016-08-24 9 views
0

私はC++で次のコードを実行しています。配列オフセットC++ pthreads戻り値

期待どおりに実行されますが、最初の結果は2番目のforループでNULLになりますが、それ以降の結果はすべて正しいです。

pthread_t pthread_t_array[thread_count]; 
    int ireturn[thread_count]; 
    float chunk_elements[thread_count]; 

    for (int i = 0; i < thread_count; i++) 
    { 
     float vector_chunk[3] = {2.0,4.0,3.0}; 

     pthread_t x; 
     pthread_t_array[i] = x; 

     ireturn[i] = pthread_create(&x,NULL,worker,(void *) vector_chunk); 
    } 

    for (int i = 0; i < thread_count; i++) 
    { 
     void * result; 
     ireturn[i] = pthread_join(pthread_t_array[i],&result); 


     // THE LINES BELOW: AT i = 0, result = NULL 
     // however, at every other value of i, 14 is returned as expected. 

     if (result != NULL){ 
      chunk_elements[i] = *(float *) result; 
     } 
     free(result); 
    } 

フルコードはhereです。

結果がNULLの場合はテストする行に配列オフセットがあります(i = 0、結果はNULLですが、他のすべてのiではそうではありません)。すべてが正しく行われているようです。

訂正:実際にはオフセットではなく、最初の値はNULLであるため、1つ少ない値があります。

+0

'pthread_t_array [i]'は有効な 'pthread_t'ではないため、参加できません。 (あなたは配列の中ではなく、(不要な)変数 'x'にそれを格納しました) – molbdnilo

+0

@molbdnilo私が何を考えているのか分かりません。 – bordeo

答えて

0

worker()コードが表示されていないスレッドが、スレッドが受け取るパラメータvector_chunkの読み取りを試みた場合、これは未定義の動作であり、バグです。

これは、vector_chunk配列に自動スコープがあり、forループ反復が終了するまで存在するからです。 pthread_create()が返され、その戻り値が配列に格納されるとすぐに、ループの繰り返しが終了し、配列vector_chunkが有効範囲外になり、事実上破棄されます。

vector_chunkがスコープ外になったときに親スレッドがそのループ反復の最後に達する前に、スレッドが実行して読み取るという保証はありません。 vector_chunkが範囲外になった後、worker()vector_chunkパラメータにアクセスしようとすると、未定義の動作とバグが発生します。

解決策は、パラメータをスレッドに動的に割り当て、初期化してからスレッドを開始し、動的に割り当てられたパラメータとすべてのスレッドパラメータデータを渡すことです。スレッドは、そのパラメータデータを取得し、そのパラメータを解放します。

+0

OK ...どうすれば正しく動作しますか(今のところ) - メインメソッドのベクタチャンクを最大スコープに変更すると修正されません。 – bordeo

+0

その質問に答えるための情報が不十分です。 stackoverflow.comのすべての質問には質問自体に[mcve]が含まれている必要があります。いつでも機能しなくなる外部サイトへのリンクは不十分です。 –