来自多个线程的pthread_cond_signal

时间:2015-03-27 07:19:35

标签: c multithreading pthreads posix

让我们想象有一个线程调用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互斥锁是否足以保证所有信号都被序列化并且不会丢失?

1 个答案:

答案 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而不是一次。