2015-06-08 73 views
0

我正在編寫一個代碼,它創建10個線程,並首先使用偶數線程ID執行這些線程,然後再執行所有使用奇數線程ID的線程。我正在使用POSIX線程庫。這是我寫的代碼:多線程程序不能生成所需的輸出

#include "stdlib.h" 
#include "pthread.h" 
#include "stdio.h" 

#define TRUE 1 
#define FALSE 0 

int EVEN_DONE = FALSE; 
int evenThreads, oddThreads = 0; 
int currentThread = 0; 

//the mutex for thread synchronization 
static pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER; 

//the condition variable; 
static pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 



void * printEven(unsigned long id) 
{ 
    pthread_mutex_lock(&mymutex); 
     evenThreads++; 
     printf("TID: %lu, Hello from even\n", id); 
     // this condition checks whether even threads have finished executing 
     if(evenThreads + oddThreads >= 10) { 
      EVEN_DONE = TRUE; 
      pthread_cond_broadcast(&cond); 
     } 
    pthread_mutex_unlock(&mymutex); 
    return NULL; 
} 

void * printOdd(unsigned long id) 
{ 
    pthread_mutex_lock(&mymutex); 

    while (!EVEN_DONE) { 
     oddThreads++; 
     pthread_cond_wait(&cond, &mymutex); 
     printf("TID: %lu, Hello from odd\n", id); 
    } 
    pthread_mutex_unlock(&mymutex); 
    return NULL; 
} 



void * threadFunc(void *arg) 
{ 
    unsigned long id = (unsigned long)pthread_self(); 
    if (id % 2 == 0) 
    { 
     printEven(id); 

    } 

    else 
    { 
     printOdd(id); 
    } 

    return NULL; 
} 

int main() 
{ 
    pthread_t* threads; 
    int num_threads = 10; 

    int i, j; 

    threads = malloc(num_threads * sizeof(threads)); 
    for (i = 0; i < 10; i++) { 
     pthread_create(&threads[i], NULL, threadFunc, NULL); 
    } 
    for (j = 0; j < 10; j++) { 

     pthread_join(threads[j], NULL); 
    } 

    printf("Finished executing all threads\n"); 

    return 0; 
} 

然而,當我運行它不會產生期望的輸出代碼。我得到的輸出是這樣的:

output image

顯然,這似乎所有的線程ID爲偶數。不過,我認爲我的代碼存在問題。我究竟做錯了什麼?我怎樣才能達到理想的輸出?

(注:我在入門級的水平是當它涉及到POSIX線程和多線程一般)提前

感謝。

+0

沒有理由(我知道)爲什麼pthreads庫不能爲其線程ID選擇偶數。事實上,如果pthreads庫將其線程ID基於一個指針值,那麼我希望它們都是,因爲指針通常是字對齊的。 –

+0

如果是這樣的話,我怎麼才能測試代碼的正確性? – avidProgrammer

+1

如果是這種情況,您需要退後一步並更正程序的假設,而不是程序本身。例如,放棄對線程ID值的假設。相反,在父線程中生成值並將每個值作爲參數傳遞給每個線程。 – kaylum

回答

3

POSIX不保證pthread_self()返回的pthread_t類型是一個數字類型,可以轉換爲unsigned long - 例如,它允許爲結構類型。

如果您希望以符合POSIX的方式編寫代碼,則需要自行分配數字線程ID。例如,你可以有:

unsigned long allocate_id(void) 
{ 
    static unsigned long next_id = 0; 
    static pthread_mutex_t id_lock = PTHREAD_MUTEX_INITIALIZER; 
    unsigned long id; 

    pthread_mutex_lock(&id_lock); 
    id = next_id++; 
    pthread_mutex_unlock(&id_lock); 
    return id; 
} 

然後在您的線程使用:

unsigned long id = allocate_id(); 

控制ID的分配自己還允許您控制序列 - 例如,在這種情況下,可以確保ID將按順序分配,以便您擁有奇數和偶數ID。