我们有一个非常接近生产者-消费者问题的问题集。实际用例是一个线程(生产者)运行一个目录列表(大约 2000 个条目),然后将这些条目提供给 4 个线程(消费者)来处理这些目录中的特定文件。
我们试图解决的问题是如何让生产者线程等待最终消费者完成后再继续。一旦我们将所有文件都存储在内存中,就需要进行后处理,只有在读取所有文件后才能完成。
我们已经实现了一个非常简单的计数器解决方案,该解决方案基于轮询类计数器的繁忙等待(计数器由生产者递增,由消费者递减,由互斥锁保护):
while(fileCnt > 0) {
usleep(10000);
}
这当然不是一个好的解决方案。
有没有办法通过条件/信号量/其他方式来做到这一点?
我们仅限于非 C++11 实现(基于 pthread)。
谢谢。
最佳答案
嗯.. 对于一般情况,这实际上很难有效地完成。如果您在提交第一个条目之前就知道要向队列提交多少个对象(就像您看起来所做的那样),那就更容易了:
将一个原子整数设置为要提交的对象数。在每个排队的项目中加载一个回调,线程在完成每个对象的处理后调用该回调。回调将 int 递减为零。当线程将其解码为零时,它会向同步对象发出信号,生产者在将其最后一个对象排队后正在等待该同步对象。
我还在考虑如果生产者正在迭代一些列表并且在排队第一个项目之前不知道结尾在哪里:(
这种情况可能需要回调中的实际锁定,以便生产者可以进入它并“自动”检查所有排队的操作是否已完成,如果没有,则在退出锁定后等待同步对象。如果同步对象保持状态会更安全,例如。一个信号量,这样就不会错过在退出锁之后但在等待之前发出的信号,(??不确定如何使用 condvar 安全地做到这一点??)。
关于c++ - 在生产者继续之前等待所有异步消费者完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26156286/