让我们想象有一个线程调用pthread_cond_wait
并等待信号:
pthread_mutex_lock(&m);
.....
while(run)
{
do {
pthread_cond_wait(&cond,&m);
} while(!got_signal);
got_signal = false;
do_something();
}
并且有多个线程可以传递信号:
pthread_mutex_lock(&m);
got_signal = true;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&m);
这个解决方案足够安全吗?如果多个线程发送信号会发生什么? m
互斥锁是否足以保证所有信号都被序列化并且不会丢失?
答案 0 :(得分:3)
在您发布的代码中,允许线程调用pthread_cond_signal()
的唯一位置是他们可以获取m
,而这只能在{{1}上阻止等待线程时发生}。
然而,在等待线程被唤醒并且可以获取互斥锁之前,可能发生两个信令线程彼此之后获取互斥锁。在这种情况下,您将丢失第二个信号(以及在等待线程运行之前可能到达的任何其他信号),因为您的等待线程只能“看到”它已经发出信号,但不会丢失多少次发生了。
为了确保您不会丢失任何信号,您可以使用计数器而不是pthread_cond_wait()
标志:
等待线程:
got_signal
信令线程:
pthread_mutex_lock(&m);
.....
while(run)
{
while(signal_count == 0) {
pthread_cond_wait(&cond,&m);
}
--signal_count;
do_something();
}
(另请注意,我已将pthread_mutex_lock(&m);
++signal_count;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&m);
循环与do...while
循环交换,以确保在仍有未处理的信号时不会调用while
。)< / p>
现在,如果多个线程最终直接相互发送信号,pthread_cond_wait()
将变为多个,这将导致等待线程多次运行其signal_count
而不是一次。