【问题标题】:pthread_cond_broadcast not signalling threadspthread_cond_broadcast 不发信号通知线程
【发布时间】:2018-06-04 22:41:56
【问题描述】:

我真的很难理解如何以让线程同时运行的方式锁定和解锁互斥锁。现在我试图让每个线程都做一些事情,然后等到所有线程都准备好,然后重复它。这应该反复发生,所以我把它全部放在一个条件循环中。我的问题是,似乎我的广播从未被任何线程接收,因为等待信号的每个线程都会永远等待,而发送信号的线程会继续。

我已经简化了我的代码,使其尽可能简单,同时仍然可以编译和运行:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>

#define num_threads 4

int repeat = 1;
int timesLooped = 0;
int waitingThreads = 0;
int threadNo = -1;
pthread_mutex_t mutex1;
pthread_cond_t condition;


//thread body
void* threadBody(void* arg){

   
   //sensitive info: requires lock
   if(pthread_mutex_lock(&mutex1)){ printf("error1\n"); }
     threadNo++;
     int threadId = threadNo;
     //other info is set here as well in my code
   if(pthread_mutex_unlock(&mutex1)){ printf("error2\n"); }

   //main loop in the thread body
   while(repeat == 1){

      if(pthread_mutex_lock(&mutex1)){ printf("error3\n"); }

      //wait until all threads are ready
      while(waitingThreads < num_threads - 1){

         printf(" %d! ", threadId);
         waitingThreads++;
         pthread_cond_wait(&condition, &mutex1);

         printf(" %d ", threadId);
         if(pthread_mutex_unlock(&mutex1)){ printf("error4\n"); }

      }
  
      //last thread will broadcast
      if(waitingThreads == num_threads - 1){

         printf("\n\nthread %d was last! broadcasting to let everyone proceed...", threadId);
         timesLooped++;
         waitingThreads = 0;
        if(timesLooped == 3){
            repeat = 0;
         }
sleep(1);
         pthread_cond_broadcast(&condition);
         if(pthread_mutex_unlock(&mutex1)){ printf("error5\n"); }
         

 


      }



   }
printf("\n\nexiting thread %d\n", threadId);
   pthread_exit((void*) arg);
}





int main(int argc, char** argv){

   pthread_t threads[num_threads];
   void* retval;

   //create threads
   for(long i = 0; i < num_threads; i++){
      pthread_create(&threads[i], NULL, threadBody, (void*) i);
   }

   //join threads
   for(long j = 0; j < num_threads; j++){
      pthread_join(threads[j], &retval);
   }


printf("\n\nDONE\n");
}

这给了我一个输出:

线程 3 是最后一个!广播让大家继续...

线程 2 是最后一个!广播让大家继续...

线程 1 是最后一个!广播让大家继续...

退出线程1(死锁,其他线程永不退出)

【问题讨论】:

  • 如果您提供实际的可编译测试(您提供的代码无效且无法编译),您会得到更好的答案。不加倍间距的奖励积分。
  • 我已将代码更新为可编译。

标签: c linux pthreads mutex


【解决方案1】:

您的程序中至少有两个错误。

  1. 你有一个数据竞争(见blog post)。

    当线程 0num_threads - 1 访问 waitingThreads 中的 if (waitingThreads == num_threads - 1) ... 时,它们会在锁之外这样做(即它们竞争)。

  2. 您不允许运行除最后一个以外的线程(这是您的主要问题)。

    pthread_cond_wait两个条件都已发出信号并且可以重新获取互斥体时返回。

    但是您的最后一个线程立即在释放互斥锁时重新获取它,因此没有其他线程可以继续。

    我希望如果您在最后一个线程中的pthread_mutex_unlock 之后添加sleepusleep,您的程序将开始按预期运行。

【讨论】:

  • 我试过让我的最后一个线程休眠一段时间,但它不会影响输出。对于互斥锁建议...我将互斥锁锁定在重复循环的顶部,所以我看不到线程如何在锁之外访问它。
  • 我解决了我的一个主要问题。我一直在增加 threadNo,然后只引用它,所以最终它总是 3。我为打印目的设置了一个新变量。我的代码已经到了一个线程可以退出的地步,但其他线程不能。
  • @Lazarus 您还没有修复任何数据竞争(实际上您添加了更多)。还有,你加了sleepbeforepthread_mutex_unlock,没用。
猜你喜欢
  • 2013-04-28
  • 2013-07-22
  • 1970-01-01
  • 1970-01-01
  • 2018-01-15
  • 1970-01-01
  • 2011-05-18
  • 2015-08-21
  • 2016-02-28
相关资源
最近更新 更多