2014-10-02 42 views
0

我们有一个非常接近生产者 - 消费者问题的问题集。实际使用情况是针对通过目录列表(生产者)运行的线程(大约2000条),然后将这些条目提供给处理这些目录中特定文件的4个线程(消费者)。在生产者继续之前等待所有异步消费者完成

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

我们已经实现了一个基于忙等待很天真计数器的解决方案,投票类计数器(计数器由生产增加,由消费者递减,由一个互斥保护):

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

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

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

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

谢谢。

+0

这些消费者正在通过cv + mtx受保护,谁的内容大小是其中的一部分谓词检查,是吗? – WhozCraig 2014-10-02 08:10:27

+1

典型的方法是有一个信号量,并预先加载队列大小的信号量(例如4,5或8,以允许生产者为消费者准备一些项目)。然后在信号量的上下用来指示剩余的空间量,当信号量为零时,它等待对方消耗下一个项目) – 2014-10-02 08:11:14

+0

@WhozCraig“我们仅限于非C++ 11实现(基于pthread)“。 ---除非你提出推荐变体。 – Jagannath 2014-10-02 08:17:15

回答

1

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

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

我还在想着这里到底是排队的第一项:(

的话,可能需要回调的实际锁定之前做什么,如果生产者是迭代一些名单,不知道这么生产者可以输入它并检查所有排队的操作是否完成,如果没有,则退出锁定后等待同步对象,如果同步对象保持状态,例如信号量,则更安全,以便在退出锁定之后,但在等待之前产生的信号不会被遗漏,(不知道如何使用condvar安全地执行它)。

+0

我们使用2个互斥对象来实现上述功能,它的工作原理相当好。谢谢。 – user626201 2014-10-06 08:18:58

相关问题