我的应用程序中连续运行了6个线程。场景是:
一个线程不断获取消息并插入消息队列。其他4个线程可以被视为工作者,它们不断从队列中获取消息并处理它们。另一个最终线程填充分析信息。
问题:
现在获取消息线程的睡眠持续时间是100毫秒。工作线程是200ms。当我运行这个应用程序时,消息提取线程正在控制并插入队列,从而增加了堆。工作线程没有机会处理消息并解除分配。最后它导致内存不足。
如何管理这种场景,以便为消息提取线程和工作线程提供平等的机会。
提前致谢:)
答案 0 :(得分:4)
您需要向生产者线程添加背压。通常,这将通过使用阻塞的消费者 - 生产者队列来完成。生产者将项目添加到队列中,消费者将队列中的项目从队列中取出并处理它们。如果queue为空,则消费者会阻塞,直到生产者添加一些东西到队列如果队列是完整的生产者块,直到消费者从队列中获取项目。
答案 1 :(得分:4)
我经常使用的一个流控制系统是在启动时创建一个大型的消息对象池,而不再创建它。 *对象存储在线程安全的阻塞“池队列”中并循环,由生产者从池中弹出,在其他阻塞队列中排队到消费者/ s然后在“消耗”时推回到池队列中
这会限制内存使用,提供流量控制,(如果池清空,生成器/块在其上,直到从消费者返回消息),并消除连续的new / delete / malloc / free。更复杂和更慢的有界队列不是必需的,并且所有队列只需要足够大以容纳(已知的)最大数量的消息。
使用'经典'阻塞队列不需要任何Sleep()调用。
答案 2 :(得分:1)
你想使用一个有界队列,当满的时候会阻塞试图入队的线程,直到有更多空间可用。
您可以使用concurrent_bounded_queue from tbb,或者只使用初始化为最大队列大小的信号量,并在出队时减少入队和递增。 boost :: thread本身不提供信号量,但你可以使用锁和条件变量来实现它。
答案 3 :(得分:1)
你的问题有点模糊,所以我可以给你这些指导而不是代码:
C ++ 11中的线程库具有实现消费者生产者应用程序所需的一切。但是,如果您无法升级编译器,也可以使用boost线程库。