2016-06-25 100 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