2013-07-25 103 views
0
#include <unistd.h> 
#include <pthread.h> 
#include <stdio.h> 
int global; 
int i = 30; 
int j = 30; 
int k = 30; 
pthread_mutex_t mutex; 
void* child1(void* arg) 
{ 
    while(k--) 
    { 
     pthread_mutex_lock(&mutex); 
     global++; 
     printf("from child1\n"); 
     printf("%d\n",global); 
     pthread_mutex_unlock(&mutex); 
    } 
} 

void* child2(void* arg) 
{ 
    while(j--) 
    { 
     pthread_mutex_lock(&mutex); 
     global++; 
     printf("from child1\n"); 
     printf("%d\n",global); 
     pthread_mutex_unlock(&mutex); 
    } 
} 

int main() 
{ 

    pthread_t tid1, tid2; 
    pthread_mutex_init(&mutex, NULL); 
    pthread_create(&tid1, NULL, child1, NULL); 
    pthread_create(&tid2, NULL, child2, NULL); 
    while(i--) 
    { 
     pthread_mutex_lock(&mutex); 
     global++; 
     printf("from main\n"); 
     printf("%d\n",global); 
     pthread_mutex_unlock(&mutex); 
    } 
    return 0; 
} 

我是新來的並行線程和多線程,該代碼的結果是從主要XXchild1出現很少,三個線程從未一起出現,有什麼問題呢?多線程(並行線程)競爭碼

+0

這是不一定的情況是'printf()的'刷新輸出與換行符使用pconditional控制,和我我不知道'printf()'的底層實現是如何工作的,但是在你開始討論更棘手的問題之前,我建議增加一個'fflush(stdout)'來確保在每次迭代時爲每個線程輸出緩衝區已經在關鍵部分之間完全刷新,並且沒有機會通過一些神奇的異步事件被覆蓋。如果簡單的檢查沒有完成,那麼擔心其他問題。 – user

回答

2

大部分時間在關鍵部分將花費在printf調用中。您可以試試:

{ 
    int local; 

    pthread_mutex_lock(& mutex); 
    local = ++global; 
    pthread_mutex_unlock(& mutex); 

    printf("from <fn>\n%d\n", local); 
} 

這仍然沒有給出任何保證然而,「公平」,但printf呼叫很可能使用一個系統調用或I/O事件,這將導致調度程序踢入。


您的程序在很多方面類似於Dining Philosophers Problem。你不想讓任何線程'餓死',但是你在全局計數器的線程之間有爭用,並且你想強制執行一個有序的執行。

+0

我如何確保所有三個線程都已執行? – nzomkxia

+0

@nzomkxia - 你不能。你將需要一些其他的pthread機制,可能是條件變量,或者是一個使用'pthread_yield'的隊列結構等。研究Dining Philosophers問題。 –

+0

儘管這裏的全局計數器並不是一個共享資源,它只是在無限期內增加(沒有分支或計算依賴於它的值,除了線路輸出以外的任何位置)。每個線程都有自己的倒計時,他們共享的唯一資源就是互斥量。我沒有看到這與餐飲哲學家的問題有何相似之處。 – user

0

代碼中的一個建議replace printf(「from child1 \ n」);到printf(「from child2 \ n」);在void * child2(void * arg)函數中。如果你想確保所有的線程完成,請在主函數結束處添加以下行。 pthread_join(tid1,NULL); pthread_join(tid2,NULL);

0

我認爲你應該使用3型動物互斥,順便說一下,以避免不安全的訪問