所以我有这个while循环,它可以处理多个线程,并且只要所有线程都正常工作,我希望它能够工作,如:
while(*threads are working*) {
pthread_mutex_lock
if(stack is not empty) {
pthread_cond_broadcast
*critical work*
pthread_mutex_unlock
}
else {
pthread_cond_wait
pthread_mutex_unlock
}
我基本上希望这个while循环运行,直到所有线程都检查堆栈是否为空并在else情况下等待。非常欢迎所有提示,谢谢。
答案 0 :(得分:2)
请记住,条件变量只是表明封闭程序中的某些条件已发生变化。使用条件变量时最重要的是要了解条件是什么并确保它正确建模。该条件通常也称为谓词。
在您的情况下,您的线程充当共享堆栈上的工作的生产者和消费者。如果线程用完了,它将进入等待状态,只有在满足下列条件之一时它才会返回:
这两个条件的分离构成了你的谓词。
第一个条件已在程序中建模,因为您只需检查堆栈以查明是否有任何新工作可用。然而,第二个条件不是。您无法检查当前处于等待状态的线程数。
解决方案是对该条件进行建模,这可以通过引入计数器轻松完成:
int threads_waiting = 0;
while(true) {
pthread_mutex_lock
if(stack is not empty) {
*critical work*
if(i_pushed_some_work_on_the_stack) {
pthread_cond_broadcast // wake up any threads that have gone to sleep
// because the stack ran out of work
}
pthread_mutex_unlock
} else {
++threads_sleeping
if(threads_sleeping == number_of_threads) {
pthread_cond_broadcast // wake up any threads waiting for
// the last thread to finish
pthread_mutex_unlock // ... and we're done!
return
}
while(true) {
pthread_cond_wait
if(stack is not empty) {
// there is more work available; continue outer loop
--threads_sleeping
break;
} else if(threads_sleeping == number_of_threads) {
// everybody is done, so let's return
pthread_mutex_unlock
return
} else {
// spurious wakeup; go back to sleep
}
}
pthread_mutex_unlock
}
请注意我们如何在谓词发生变化时调用pthread_cond_broadcast
,并且在从pthread_cond_wait
返回后我们会检查封闭条件以确定下一步该做什么。