处理C ++中的boost线程竞争条件

时间:2012-12-19 11:40:05

标签: c++ multithreading boost

我的应用程序中连续运行了6个线程。场景是:

一个线程不断获取消息并插入消息队列。其他4个线程可以被视为工作者,它们不断从队列中获取消息并处理它们。另一个最终线程填充分析信息。

问题:

现在获取消息线程的睡眠持续时间是100毫秒。工作线程是200ms。当我运行这个应用程序时,消息提取线程正在控制并插入队列,从而增加了堆。工作线程没有机会处理消息并解除分配。最后它导致内存不足。

如何管理这种场景,以便为消息提取线程和工作线程提供平等的机会。

提前致谢:)

4 个答案:

答案 0 :(得分:4)

您需要向生产者线程添加背压。通常,这将通过使用阻塞的消费者 - 生产者队列来完成。生产者将项目添加到队列中,消费者将队列中的项目从队列中取出并处理它们。如果queue为空,则消费者会阻塞,直到生产者添加一些东西到队列如果队列是完整的生产者块,直到消费者从队列中获取项目。

答案 1 :(得分:4)

我经常使用的一个流控制系统是在启动时创建一个大型的消息对象池,而不再创建它。 *对象存储在线程安全的阻塞“池队列”中并循环,由生产者从池中弹出,在其他阻塞队列中排队到消费者/ s然后在“消耗”时推回到池队列中

这会限制内存使用,提供流量控制,(如果池清空,生成器/块在其上,直到从消费者返回消息),并消除连续的new / delete / malloc / free。更复杂和更慢的有界队列不是必需的,并且所有队列只需要足够大以容纳(已知的)最大数量的消息。

使用'经典'阻塞队列不需要任何Sleep()调用。

答案 2 :(得分:1)

你想使用一个有界队列,当满的时候会阻塞试图入队的线程,直到有更多空间可用。

您可以使用concurrent_bounded_queue from tbb,或者只使用初始化为最大队列大小的信号量,并在出队时减少入队和递增。 boost :: thread本身不提供信号量,但你可以使用锁和条件变量来实现它。

答案 3 :(得分:1)

你的问题有点模糊,所以我可以给你这些指导而不是代码:

  1. 使用Mutex保护互动数据。在多线程consumer producer问题中,通常在共同数据(程序中的消息)上存在竞争条件。一个线程试图在相互存储器位置上写入而另一个线程试图从相同位置读取。阅读器读取的消息可能已损坏,因为作者在阅读过程中已经将其写入。您可以使用互斥锁锁定相互内存位置。每个线程都应获取此锁,以便能够读取或修改相互数据。这样,消费者流程将绝对确保数据未被修改。但是,您应该注意,获取此锁可能会阻止生产者线程,因此您应该尽快释放锁。
  2. 使用条件变量通知消费者线程。如果您不使用通知机制,则所有使用者线程都应主动检查将耗尽系统资源的数据生成。知道生成器线程会在消息准备就绪时通知他们,消费者线程应该很容易进入休眠状态。
  3. C ++ 11中的线程库具有实现消费者生产者应用程序所需的一切。但是,如果您无法升级编译器,也可以使用boost线程库。