2017-05-30 56 views
1

pthread_cond_wait允许我们等待,直到条件变量获得信号。如何等待任何条件变量?

但是,是否有机会等到两个条件变量中的任何一个发出信号?

我问的原因是我有以下情况:我有42个线程和两个可能的谓词,这些线程可能会继续他们的工作。如果满足这两个谓词中的任何一个,他们可以继续工作。

但是,问题是,当这些谓词中的一个被满足时,那么只有一个线程和一个特定的线程,而不是任何线程都可以继续工作。如果另一个满足,则应该恢复所有线程。

所以,我的想法是有一个条件变量,每当第二个pred被满足时被广播......还有另外42个条件变量,每个条件变量都与一个线程相关联。当第一个预测被实现时,它们中的适当的一个将被发信号通知。

但是,这需要线程唤醒时,只要有任何给定的cond变量被发信号通知...有什么机会实现这一点?

+1

我认为43个线程是最简单的方法:一个用于大规模并行作业的42个线程的线程池和一个用于单线程作业的线程的“线程池”。或者可以使用一个信号量而不是一个条件变量,并将适当的次数发布到信号量。 –

回答

0

不,你只能等待一个条件变量。

但是,这很好。当一个线程从pthread_cond_wait()中被唤醒时,必须检查它所等待的谓词实际上是否为真 - 这是因为等待条件变量允许随时被唤醒(称为“虚假唤醒”) 。

因此,由于您的线程必须检查是否允许在pthread_cond_wait()返回时继续进行操作,因此您可以使用与pthread_cond_broadcast()配对的单个条件变量。线程本身决定(基于检查由互斥锁保护的共享状态)他们是单独允许继续还是应该继续等待。所以,这样的事情:

pthread_mutex_lock(&lock); 

while (!this_thread_can_proceed(state) && !all_threads_can_proceed(state)) 
    pthread_cond_wait(&cond, &lock); 

或者,你允许他们等到上使用相同的互斥多个条件变量(反之不允许的),这样你就可以在每一个线程等待其自己的条件变量,然后唤醒线程或者发信号通知单个条件变量,或者循环遍历该集合发信号通知它们,取决于它已经满足哪个谓词。

这些解决方案中哪一个性能更好取决于应用程序中“所有线程”和“一线程”唤醒之间的平衡。

+0

看起来像可怕的表现。 AFAIK切换线程足够昂贵。保证O(线程数量)无用的上下文切换......看起来很不干净,即使最后它并不重要。要么是,要么清洁的定义是NeverToOptimizePrematurely,而不是AvoidExecutingCodeYouKnowToBeUseless。 – gaazkam

+0

@gaazkam:我已经编辑了答案,以提供一种不受您引用的“雷鸣群体”问题影响的替代解决方案。 – caf