2012-02-29 22 views
2

我正在練習一些多線程程序,但我無法確定這個輸出的邏輯。帶有pthread函數的靜態存儲

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

int print_message(void* ptr); 

int main() 
{ 
pthread_t thread1,thread2; 
char *mesg1 = "Thread 1"; 
char *mesg2 = "Thread 2"; 

int iret1, iret2; 

pthread_create(&thread1, NULL, print_message, (void *)mesg1); 
pthread_create(&thread2, NULL, print_message, (void *)mesg2); 

pthread_join(thread1,(void*)&iret1); 
pthread_join(thread2, (void*)&iret2); 

printf("Thread 1 return : %d\n", (int)iret1); 
printf("Thread 2 return : %d\n", (int)iret2); 
return 0; 

} 

int print_message(void *ptr) 
{ 
char *mesg; 
static int i=0; 
mesg = (char *)ptr; 
printf("%s\n",mesg); 
i++; 
return ((void*)i); 

} 

我期待輸出

Thread 1 
Thread 2 
Thread 1 return : 1 
Thread 2 return : 2 

,但我得到的輸出

Thread 1 
Thread 2 
Thread 1 return : 0 
Thread 2 return : 2 

可能有些請澄清一下給我?請指出是否有使用pthread函數的錯誤。

回答

4

變量i在兩個線程之間共享,因爲它是static。修改多個線程之間的變量的行爲是未定義的,因此,實際上,您所得到的輸出和您想要得到的輸出在編譯器沒有義務向您提供的意義上是「錯誤的」。事實上,根據我使用的優化級別,我能夠獲得輸出結果,並且基於該平臺無疑會有所不同。

如果你想修改i,你應該使用一個互斥體:

int print_message(void *ptr) 
{ 
    static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 
    char *mesg; 
    static int i=0; 
    int local_i; 

    mesg = (char *)ptr; 
    printf("%s\n",mesg); 
    if (pthread_mutex_lock(&mutex) == 0) { 
    local_i = ++i; 
    pthread_mutex_unlock(&mutex); 
    } 
    return ((void*)local_i); 
} 

如果不使用互斥,你將永遠不會被一定讓你認爲你應該得到的輸出。

3

關於多線程有幾本好書。我發現相當有趣Butenhof's "Programming with Posix threads",但更新的書籍存在。

你有沒有看過他們中的任何一個,還是很好的pthreads tutorial在線?

基本上,每個程序源代碼線程都可能不像您期望的那樣直觀地查看內存。 (cache coherencemulti-processingmemory modelC11 ...)

實際上來說,線程之間共享的數據的任何接入應由synchronization基元,例如被保護mutexesrwlocks

在開始編碼之前,你應該理解這些問題。調試多線程程序是一個噩夢(非確定性,heisenbugs)。