我想我错过了关于多道程序设计的基本设计模式。 我解决了一个问题,但我会说它过于复杂。
在程序启动时,我正在分配一个静态的工作池和一个主线程,它贯穿整个程序运行。 (下面的伪代码)
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条件。
它有效但不美观,任何改进的想法都非常受欢迎。
感谢。
答案 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可以继续。
环状屏障类似于锁存,除了屏障是周期性的,允许它无限重置。 因此,在主要处于循环中的情况下,循环障碍是更好的选择。