1

複数のスレッド (以下の例では 10 個) を作成し、それぞれに関数を実行させたいと考えています。

これが私のコードです:

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

typedef struct arg_struct {
    int id;
    int val;
} arg_struct;

void *printarg(void *params) {
    arg_struct *args = (arg_struct *) params;
    printf("id %i value %i\n", args->id, args->val);
    return 0;
}

int main() {
    int i = 0;
    pthread_t threads[10];
    for (i = 0; i < 10; i++) {
        arg_struct arg;
        arg.id = i;
        arg.val = i + 10;
        pthread_create(&(threads[i]), NULL, &printarg, &arg);
    }
    for (i = 0; i < 10; i++) {
        pthread_join(threads[i], NULL);
    }
    return 0;
}

実行中に次のような出力が期待されていました。

id 0 value 10
id 1 value 11
id 2 value 12
id 3 value 13
id 4 value 14
id 5 value 15
id 6 value 16
id 7 value 17
id 8 value 18
id 9 value 19

しかし、代わりに次のような出力が得られます。

id 2 value 12
id 3 value 13
id 3 value 13
id 4 value 14
id 6 value 16
id 6 value 16
id 9 value 19
id 9 value 19
id 9 value 19
id 9 value 19

プログラムを再実行するたびに、出力がわずかに変化します。id と value が繰り返され、パターンが不規則に見えます。

何が起こっている?子スレッドも for ループでスレッドを作成しているため、繰り返しが発生していますか? もしそうなら、私が読んだ pthread_create の例の多くで、人々は N 回反復して N 個のスレッドを作成するループを使用しているように見えたので、私は混乱しています (上記とまったく同じです)。したがって、上記のコードでは、1 つのマスター スレッドが N 個の子スレッドを作成すると仮定しましたか? 私が間違っている?前もって感謝します。

4

1 に答える 1

7

arg_struct各スレッドには、ループ内で宣言されたへのポインタが渡されます。このポインタは、反復ごとに新しく作成されます。ループを終了するまでどのスレッドも実行されない場合、技術的にはスコープ外の変数を参照しています。スコープ外に出ていなくても (たとえば、 の先頭で宣言したとしますmain)、そこに配置した最終的な値がすべてのユーザーに表示されます。あなたのトレースから、スレッドはループに対してランダムな塊で始まっているようです。

スレッドごとに個別に割り当てる必要がありarg_struct、それぞれがスレッドの存続期間中有効であることを確認してください。

これを試して:

#define NUM_THREADS 10

int main() {
    int i = 0;
    pthread_t threads[NUM_THREADS];
    arg_struct args[NUM_THREADS];
    for (i = 0; i < NUM_THREADS; i++) {
        args[i].id = i;
        args[i].val = i + 10;
        pthread_create(&threads[i], NULL, &printarg, &args[i]);
    }
    for (i = 0; i < NUM_THREADS; i++) {
        pthread_join(threads[i], NULL);
    }
    return 0;
}
于 2014-03-17T02:09:05.383 に答える