2017-02-02 7 views
0

forループのインデックスをpthread_createの引数にラッパーオブジェクトを介して渡したいとします。ただし、スレッドから印刷された整数が正しくありません。 以下のコードが特別な順序で印刷されることを期待しました。forループインデックスをCのpthread_create引数オブジェクトに渡す

IDは、この代わりに整数1,3スレッド

に渡されることはない印刷しかし、IDは3であり、IDは2であり、IDが1である、0

ありますIDが0であり、IDは0であり、IDは、IDが2であり、0である

struct thread_arg { 
int id; 
void * a; 
void * b; 
} 

void *run(void *arg) { 
struct thread_arg * input = arg; 
int id = input->id; 
printf("id is %d, ", id) 
} 

int main(int argc, char **argv) { 
for(int i=0; i<4; i++) { 
    struct thread_arg arg; 
    arg.id = i; 
    arg.a = ... 
    arg.b = ... 
    pthread_create(&thread[i], NULL, &run, &arg); 
} 

}

答えて

1

struct thread_argは自動ストレージ内にあり、その範囲はforループ内にのみ存在します。さらに、これらのうちの1つだけがメモリにあり、同じスレッドをそれぞれ別のスレッドに渡しています。この同じオブジェクトのIDを4回変更してIDをワーカースレッドに印刷する間に、データ競合を作成しています。さらに、forループが存在すると、そのメモリは有効範囲外になり、もはや有効ではなくなります。ここでスレッドを使用しているので、スケジューラーはメインスレッドまたは任意の子スレッドを自由に実行できるので、プリントアウトに関する一貫性のない動作が予想されます。子スレッドに渡す前に、それぞれstruct thread_argまたはmallocの配列を作成する必要があります。

#define NUM_THREADS 4 

struct thread_arg { 
    int id; 
    void * a; 
    void * b; 
} 

void *run(void *arg) { 
    struct thread_arg * input = arg; 
    int id = input->id; 
    printf("id is %d, ", id) 
} 

int main(int argc, char **argv) { 
    struct thread_arg args[NUM_THREADS]; 
    for(int i=0; i<NUM_THREADS; i++) { 
    args[i].id = i; 
    args[i].a = ... 
    args[i].b = ... 
    pthread_create(&thread[i], NULL, &run, &args[i]); 
    } 

    // probably want to join on threads here waiting on them to finish 
    return 0; 
} 
+0

これは機能します。助けてくれてありがとう :) – GucciProgrammer

関連する問題