在生产者继续之前等待所有异步消费者完成

时间:2014-10-02 07:40:02

标签: c++ linux multithreading pthreads posix

我们的问题集非常接近生产者 - 消费者问题。实际用例是通过目录列表(大约2000个条目)运行的线程(生产者),然后将这些条目提供给处理这些目录中特定文件的4个线程(消费者)。

我们试图解决的问题是如何让生产者线程在继续之前等待最终的消费者完成。一旦我们将所有文件都放在内存中,只有在读取了所有文件后才能进行后处理。

我们已经实现了一个非常天真的计数器解决方案,它基于繁忙的等待轮询一个类计数器(计数器由生产者递增,由消费者递减,由互斥锁保护):

   while(fileCnt > 0) {
     usleep(10000);
  }

这不是一个很好的解决方案。

有没有办法通过条件/信号量/其他方式来做到这一点?

我们仅限于非C ++ 11实现(基于pthread)。

感谢。

1 个答案:

答案 0 :(得分:1)

嗯......对于一般情况来说,这实际上很难以有效的方式进行。如果您在提交第一个条目之前知道要将多少个对象提交到队列中(如您所做的那样),那就更容易了:

将原子整数设置为要提交的对象数。在线程在处理完每个对象后调用的每个排队项目中加载一个回调。回调将int递减为零。当一个线程将其判断为零时,它会向一个同步对象发出信号,生成器在排队其最后一个对象后正在等待该对象。

我还在考虑如果制作人正在迭代一些列表并且在排队第一个项目之前不知道结尾的位置该怎么办:(

这种情况可能需要在回调中实际锁定,以便生产者可以输入它并原子地检查'如果所有排队的操作都已完成,如果没有,则在退出锁之后等待同步对象。如果同步对象保持状态,则更安全,例如。一个信号量,所以在退出锁之后但在等待之前发出的信号不会错过,(??不确定如何用condvar安全地做到这一点?)。