2016-10-11 19 views
1

私は大きなプログラムをデバッグする簡単なプログラムを作成しようとしたので、以下のプログラムと幾分似た機能を必要とするプロジェクトに取り組んでいます。私が作成しているスレッドは、期待される出力と矛盾する値を返していますが、戻り値はランダムではありません。スレッドが他のスレッドから値を返すようになったり、返される変数( "tmp")が更新されているようです。スレッドの戻り値が期待される出力と一致しません

期待される出力があるべき...

#include <stdio.h> 
#include <pthread.h> 

struct Numbers { 
    int x; 
    int y; 
}; 

void *go(void* param) 
{ 
    struct Numbers* nums = (struct Numbers*) param; 
    int sum = nums -> x + nums -> y; 

    return (void*) sum; 
} 

int main() 
{ 
    int result[2][2]; 
    int tmp; 

    pthread_t thread[2][2]; 

    int i, j; 
    for(i=0;i<2;i++) 
    { 
     for(j=0;j<2;j++) 
     { 
      struct Numbers nums; 
      nums.x = i; 
      nums.y = j; 

      pthread_create(&thread[i][j], NULL, go, &nums); 
     } 
    } 

    for(i=0;i<2;i++) 
    { 
     for(j=0;j<2;j++) 
     { 
      pthread_join(thread[i][j], (void*) &tmp); 
      result[i][j] = tmp; 
     } 
    } 

    for(i=0;i<2;i++) 
    { 
     for(j=0;j<2;j++) 
     { 
      printf("%d\t", result[i][j]); 
     } 
     printf("\n"); 
    } 

    return 0; 
} 
+4

は、スレッドがアクセスしようとする可能性がある場合に比べてnums' 'の寿命を考えてみましょう。 – GManNickG

+1

あなたは 'nums'を保証しますか?すべてのスレッド呼び出しのために書き直されませんか? – dvhh

+0

@GManNickG私は完璧な "オハイ"の瞬間がありました。スレッドが作成される前に(ネストされたfor-loopの外で)すべてのデータを準備する唯一の選択肢がありますか、それとも良いオプションがありますか? –

答えて

2

あなたは、スレッドが始まると、おそらく存在しないでしょう変数のアドレスを渡しています少なくとも1つのスレッドが他のスレッドがそれを読んでいる間にそれを書き込むので、少なくとも1つのスレッドがそれを書き込むので、データ競合である。

一般的な解決策は、スレッドの引数と結果の両方を動的に割り当て、呼び出し元とスレッドがそのように通信できるようにすることです。

例:

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 

struct threadargs { 
    int x; 
    int y; 
}; 

struct threadresults { 
    int sum; 
    int product; 
}; 

void* threadfunc(void* args_void) { 
    // Get thread args in usable type. 
    struct threadargs* args = args_void; 
    struct threadresults* results = NULL; 

    //Compute. 
    int sum = args->x + args->y; 
    int product = args->x * args->y; 

    // Return the result.  
    results = malloc(sizeof(*results)); 
    results->sum = sum; 
    results->product = product; 

    free(args); 
    return results; 
} 

int main() 
{ 
    pthread_t thread[2][2]; 
    struct threadresults* results[2][2] = {0}; 

    int i, j; 
    for (i = 0;i < 2; ++i) { 
     for (j = 0; j < 2; ++j) { 
      struct threadargs* args = malloc(sizeof(*args)); 
      args->x = i; 
      args->y = j; 

      pthread_create(&thread[i][j], NULL, threadfunc, args); 
     } 
    } 

    for (i = 0; i < 2; i++) { 
     for (j = 0; j < 2; j++) { 
      void* result; 
      pthread_join(thread[i][j], &result); 
      results[i][j] = result; 
     } 
    } 

    for (i = 0; i < 2; i++) { 
     for (j = 0; j < 2; j++) { 
      printf("sum: %d\tproduct: %d\n", 
        results[i][j]->sum, results[i][j]->product); 
     } 
    } 

    for (i = 0; i < 2; i++) { 
     for (j = 0; j < 2; j++) { 
      free(results[i][j]); 
     } 
    } 

    return 0; 
} 
関連する問題