2016-06-25 66 views
0

我們正在嘗試爲生命遊戲找到一個很好的同步。第二個線程不會從cond_wait中喚醒

因此,我們有一個打印機線程和當前有兩個線程計算下一個要打印出來的新一代單元。

計算線程只能開始計算新一代的遊戲,如果舊的已經打印。

因此,我們使用從應該喚醒兩個計算線程的打印機線程。

出於某種原因,只有一個線程在pthread_cond_wait()

我們已經嘗試使用廣播,而不是信號醒來,但沒有任何效果。

這是我們的打印機線程做什麼:

field -> printed = true; 
//pthread_mutex_unlock(&(field -> print_mutex)); 
int status = pthread_cond_signal(&(field -> print_signal)); 

這就是我們的計算線程做:

while(!field -> printed){ 
    printf("waiting for print_signal: %d\n", field -> printed); 
    pthread_mutex_unlock(&(field -> print_mutex)); 
    pthread_cond_wait(&(field -> print_signal), &(field -> print_mutex)); 
    printf("print_signal received: %d\n", field -> printed); 
} 
printf("print_signal received2: %d\n", field -> printed); 
pthread_mutex_unlock(&(field -> print_mutex)); 

然後計算線程做他們的計算,等到每個線程完成他們成立之前字段 - >打印回false。

我們覺得我們仍然不太瞭解如何正確使用互斥鎖。

回答

1

pthread_cond_signal()恰好表示等待的所有線程中的一個線程。

從Linux的pthread_cond_signal文檔:

pthread_cond_signal會重新啓動正在等待條件變量COND一個線程。

通知所有等待使用的線程pthread_cond_broadcast

從Linux的pthread_cond_broadcast文檔:

調用pthread_cond_broadcast重新啓動所有正在等待條件變量COND線程。

POSIX documentations的說:

調用pthread_cond_broadcast()功能必須解除封鎖目前被阻塞在指定條件變量COND所有線程。

pthread_cond_signal()函數將取消阻塞至少一個在指定條件變量cond上阻塞的線程(如果cond上有任何線程被阻塞)。


你也想調用pthread_cond_wait()之前鎖定互斥。當線程進入等待狀態時,互斥鎖就會隱式解鎖。

還要注意,pthread_cond_wait()後返回的互斥體再次被鎖定。

要遵循這個concpet你可以改變你的代碼看起來像這樣:

pthread_mutex_lock(&(field -> print_mutex)); 

while (!field -> printed) 
{ 
    pthread_cond_wait(&(field -> print_signal), &(field -> print_mutex)); 
} 

pthread_mutex_unlock(&(field -> print_mutex)); 

還要確保寫的標誌,而不保護

pthread_mutex_lock(&(field -> print_mutex)); 

field -> printed = true; 
pthread_cond_signal(&(field -> print_signal)); 

pthread_mutex_unlock(&(field -> print_mutex)); 

最後採取這樣的建議:在你真正的代碼添加錯誤檢查*所有那些pthread_*()電話!


而且^你確實確認了狀態和互斥對象已經正確使用了,不是嗎? ;-)

+0

非常感謝!一切工作現在完美:) – Meowzen