2011-10-25 28 views
1

私は自分自身にpthreadsスレッドを教えようとしています。私はコンパイルし、正しく実行以下のソースを、持っている:この例でpthread_joinがスレッドの配列を正しく閉じないのはなぜですか?

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

#define PTHREAD_COUNT 10 
#define FREQ 5 

void *thread_function(void *arg) { 
    int *incoming = (int *)arg; 
    int freqIdx; 

    for (freqIdx = 0; freqIdx < FREQ; freqIdx++) 
    fprintf(stdout, "Hello, world (thread %d)\n", *incoming); 

    return NULL; 
} 

int main(int argc, char **argv) { 
    pthread_t thread_IDs[PTHREAD_COUNT]; 
    void *exit_status; 
    int threadIdx; 

    for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++) { 
    pthread_create(&thread_IDs[threadIdx], NULL, thread_function, &threadIdx); 
    pthread_join(thread_IDs[threadIdx], &exit_status); 
    } 

    return 0; 
} 

私は、次の結果が得られます。

Hello, world (thread 0) 
Hello, world (thread 0) 
Hello, world (thread 0) 
Hello, world (thread 0) 
Hello, world (thread 0) 
Hello, world (thread 1) 
... 
Hello, world (thread 9) 

I pthread_create場合は、別のループを超えるpthread_t型の配列、その後、pthread_joinループすると、物事は失敗します:

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

#define PTHREAD_COUNT 10 
#define FREQ 5 

void *thread_function(void *arg) { 
    int *incoming = (int *)arg; 
    int freqIdx; 

    for (freqIdx = 0; freqIdx < FREQ; freqIdx++) 
    fprintf(stdout, "Hello, world (thread %d)\n", *incoming); 

    return NULL; 
} 

int main(int argc, char **argv) { 
    pthread_t thread_IDs[PTHREAD_COUNT]; 
    void *exit_status; 
    int threadIdx; 

    /* here I split the thread _create and _join steps into separate loops */ 

    for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++) 
    pthread_create(&thread_IDs[threadIdx], NULL, thread_function, &threadIdx); 

    for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++) 
    pthread_join(thread_IDs[threadIdx], &exit_status); 

    return 0; 
} 

これからの出力はかなり間違っています。各スレッドから5つのfprintfステートメントを取得する代わりに、スレッド2と3から1つまたは2つ、スレッド0から約20から25 Hello, worldステートメントを取得します。

これはなぜ失敗しますか?

答えて

1

他にも述べたように、問題はすべてのスレッド間で変数threadIdxを共有していることです。これを修正する1つの方法は、スレッドごとに1つの変数を作成することです。

int threadIdx; 
int indexes[PTHREAD_COUNT]; 

for (threadIdx = 0; threadIdx < PTHREAD_COUNT; threadIdx++) { 
    indexes[threadIdx] = threadIdx; 
    pthread_create(&thread_IDs[threadIdx], NULL, thread_function, &indexes[threadIdx]); 
} 
2

1つの問題は、ローカル変数threadIdxにアドレスを与えていることです。ループでそれを変更すると、スレッドが参照する値も変更されます。したがって、threadIdxの値は正しくありません。

2番目のループでは、threadIdxを再び0に設定し、スレッドが終了するのを待って、なぜスレッド0を印刷するのが多く表示されるのか説明します。

単純にthreadIdxを渡し、代わりにvoid * argsをintとして解釈することができます(sizeof(int)< = sizeof(void *)と通常はほとんどのマシンで保証されるため)。正しい出力が得られるはずです。

1

同じthreadIdx変数へのポインタをすべてのスレッドに渡します。

関連する問題