pthread_cond_signal 来自多个线程

pthread_cond_signal from multiple threads

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

在您发布的代码中,唯一允许线程调用 pthread_cond_signal() 的地方是它们可以获取 m,并且只有当您的等待线程在 [= 上被阻塞时才会发生这种情况14=].

但是,在等待线程被唤醒并可以获取互斥锁之前,两个发信号线程可能会先获取互斥锁。在这种情况下,您将丢失第二个信号(以及此后可能到达的任何其他信号,在等待线程 运行s 之前),因为您的等待线程只能 "see" 它已收到信号,但不知道发生了多少次。

为确保您不会丢失任何信号,您可以使用计数器代替 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 循环,以确保在仍有未处理的信号时不会调用 pthread_cond_wait()。 )

现在,如果多个线程最终直接发出信号,signal_count 将变得不止一个,这将导致等待线程 运行 其 do_something() 多次只有一次。