表示一批线程已完成到masterthread

时间:2011-05-30 04:57:55

标签: c++ c multithreading pthreads

我想我错过了关于多道程序设计的基本设计模式。 我解决了一个问题,但我会说它过于复杂。

在程序启动时,我正在分配一个静态的工作池和一个主线程,它贯穿整个程序运行。 (下面的伪代码)

void *worker(){
   while(1){
   //perworker mutex lock
   //wait for workerSIGNAL
   //do calculations
   //perworker mutex unlock
   }
}

我的主线程向我的所有工作人员发出信号,当工人完成时,他们等待来自主线程的下一个信号。 (下面的伪代码)

void *master(){
  while(1){
    //masterMutex lock
    //wait for masterSignal
    //signal all workerthread to start running
    /*
      SHOULD WAIT FOR ALL WORKER THREADS TO FINISH 
      (that is when workers are done with the calculations,
      and are waiting for a new signal) 
     */
    //materMutex unlock
  }
}

我的主线程从我的代码的另一部分(非线程)获取信号,这意味着只存在一个masterthread。 (下面的伪代码)

double callMaster(){
  //SIGNAL masterThread
  //return value that is the result of the master thread
}

我的问题是,如何让masterthread等待所有工人完成(等待下一个workerSignal)?

我的解决方案非常复杂。 我的workerthreads中有一个障碍,等待所有工作线程完成,然后从我的一个线程(threadId = 0),我发出一个在我的masterthread底部等待的一个workerDone条件。

它有效但不美观,任何改进的想法都非常受欢迎。

感谢。

3 个答案:

答案 0 :(得分:3)

您是否考虑过使用pthread_join http://kernel.org/doc/man-pages/online/pages/man3/pthread_join.3.html?这听起来像是使用信号在线程之间进行通信。虽然这在某些情况下可能是合适的,但我认为在您的情况下,您可能会发现使用pthread_join可以简化代码。

我在下面概述了一些示例伪代码:

//this goes in your main thread
for (int i = 0; i < num_threads; ++i)
    pthread_join(thread_id[i], ...

这样你的主线程就会阻塞,直到thread_id数组中的所有线程,你的工作线程都已终止。

答案 1 :(得分:2)

您想要使用障碍物。使用计数N初始化障碍,当任何线程调用pthread_barrier_wait时,它会阻塞,直到总共N个线程处于pthread_barrier_wait,然后它们全部返回并且屏障可以再次使用(具有相同的计数)。

有关详细信息,请参阅POSIX中的文档:

http://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_barrier_wait.html

答案 2 :(得分:0)

在Java中,您可以在此使用循环障碍,其初始值等于工作线程数。

对此屏障的引用将传递给每个工作线程,在一次执行其工作结束时,该线程会调用barrier.await()。

主程序将在屏障处等待(),直到所有工作线程都到达执行点并调用barrier.await()。

只有当所有工作线程都调用了barrier.await()时,才会提升屏障并且main可以继续。

环状屏障类似于锁存,除了屏障是周期性的,允许它无限重置。 因此,在主要处于循环中的情况下,循环障碍是更好的选择。