线程和等待条件

我正在学习pthread和等待条件。 据我所知,一个典型的等待线程是这样的:

pthread_mutex_lock(&m); while(!condition) pthread_cond_wait(&cond, &m); // Thread stuff here pthread_mutex_unlock(&m); 

我不明白的是为什么即使我使用pthread_cond_signal()来唤醒线程, while(!condition)也是必需的。

我可以理解,如果我使用pthread_cond_broadcast()我需要testing条件,因为我唤醒了所有等待的线程,其中一个可以使条件再次解锁之前的虚假(从而转移到另一个应执行在那一刻执行)。 但是,如果我使用pthread_cond_signal()我只唤醒一个线程,所以条件必须是真实的。 所以代码可能是这样的:

 pthread_mutex_lock(&m); pthread_cond_wait(&cond, &m); // Thread stuff here pthread_mutex_unlock(&m); 

我读了一些关于可能发生的虚假信号。 这(是唯一的)这个原因吗? 为什么我应该有虚假singnals? 或者还有别的东西我不明白

我假设信号代码是这样的:

 pthread_mutex_lock(&m); condition = true; pthread_cond_signal(&cond); // Should wake up *one* thread pthread_mutex_unlock(&m); 

您应该将pthread_cond_wait放在while循环中的真正原因不是由于虚假的唤醒。 即使你的条件variables没有虚假的唤醒,你仍然需要循环来捕捉一个常见的错误types。 为什么? 考虑如果多个线程在相同的条件下等待会发生什么情况:

 Thread 1 Thread 2 Thread 3 check condition (fails) (in cond_wait) unlock mutex (in cond_wait) wait lock mutex set condition signal condvar unlock mutex lock mutex check condition (succeeds) do stuff unset condition unlock mutex (in cond_wait) wake up (in cond_wait) lock mutex <thread is awake, but condition is unset> 

这里的问题是线程在等待之前必须释放互斥锁,可能允许另一个线程“窃取”线程正在等待的任何东西。 除非保证只有一个线程可以在这种情况下等待,否则在线程唤醒时假定条件是有效的是不正确的。

假设你不检查条件。 那么通常你不能避免下面的坏事发生(至less,你不能避免在一行代码中):

  Sender Receiver locks mutex sets condition signals condvar, but nothing is waiting so has no effect releases mutex locks mutex waits. Forever. 

当然你的第二个代码示例可以避免这样做:

 pthread_mutex_lock(&m); if (!condition) pthread_cond_wait(&cond, &m); // Thread stuff here pthread_mutex_unlock(&m); 

那么肯定是这样的,如果只有最多一个接收者,并且如果cond_signal是唯一可以唤醒它的话,那么只有当条件被设置时才醒来,因此不需要循环。 没有涵盖为什么第二个“如果”是不正确的。