2011-10-25 60 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) 

如果我pthread_createpthread_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; 
} 

從這個輸出是相當錯誤的。而不是從每個線程得到五個fprintf聲明,我從線程0獲得一個或兩個來自線程2和3以及大約20到25個Hello, world語句。

爲什麼這會失敗?

回答

1

正如其他人所說,你的問題是在所有線程之間共享一個threadIdx變量。解決此問題的一種方法是爲每個線程創建一個變量:

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

我看到的一個問題是你給它的局部變量threadIdx的地址。當你在循環中修改它時,線程看到的值也會改變。所以threadIdx值將不正確。

在第二個循環中,您再次將threadIdx設置爲0,並等待線程完成,這就解釋了爲什麼您看到很多打印線程0的原因。

您可以簡單地傳遞threadIdx,然後將void * args解釋爲int(因爲sizeof(int)< = sizeof(void *)並且通常可以在大多數機器上保證)並且您應該得到正確的輸出。

1

您將指針傳遞給所有線程的變量threadIdx