我目前有一个拥有大量线程的应用程序,这使得应用程序非常庞大。每个线程都是长时间运行的,基本上是新的电子邮件轮询的无限循环然后处理它们。每个线程都保持一个SSL连接,这就是线程适用于应用程序的原因。
我想使用线程池。最简单的方法是只修复线程数,然后每个线程添加10个用户,但即使在这一点上,它似乎也不像1个用户/线程那样统一工作,因为每个循环处理起来相当长。另外,这实际上不是一个线程池。
我的问题是 - 这里适当的设计模式是什么(因为它肯定比我上面写的更聪明),是否有一个C ++库可以很好地处理这个问题?将我指向Java实用程序也是有帮助的,因为根据我的经验,从Java实用程序中设计模式非常容易。
答案 0 :(得分:3)
一个用户/线程可能是一个很好的起点。阻止或可以阻塞的任何东西都需要在自己的线程中运行,以避免被其他执行代码占用或阻塞。如果电子邮件的实际处理将直接运行,则可以将其放置在" runnable"中,以使用Java术语,并提交给线程池。 Java术语将是ThreadPoolExecutor,并且自己编写一个简单的术语并不困难。您希望每个可能的CPU核心都有一个线程可以从您的计算机中获得最多的工作。
如果每封电子邮件的工作不是很好,那么跳过线程池并在读者线程上完成工作可能会更简单,更快捷。你已经支付了运行它的费用,你也可以从中获得所有的工作。
另一方面,如果处理电子邮件涉及阻止或被阻止,您可能需要为每封电子邮件启动一个新线程。您最终可以使用 lot 线程,但它可以从您的计算机中获得最大的工作量。您不希望落后于您的电子邮件,CPU使用率仅为5%。
答案 1 :(得分:1)
我在后端与一个线程池消费者之间放置了一个BlockingDeque。这使电子邮件生产者与消费者脱钩,并允许您在后端汇集消费者。看看这个:
答案 2 :(得分:1)
有许多模式可以解决问题,但做出决定的关键是理解模式的后果。 ACE website有一些可能适合的并发模式的论文,例如Active Object,Proactor和Reactor。这些示例是C ++,但如果您继续执行自己的实现,则会有一些图表和说明。
proactor可以提供优雅的解决方案或作为另一种模式的基础。对于C ++实现,我建议使用boost::asio
库:
boost::asio
与线程池一起使用。答案 3 :(得分:0)
我真的不明白你的陈述“似乎没有像1个用户/线程一样平衡工作,因为每个循环处理起来相当长”。
无论如何,Active Object模式在您的情况下可能是优雅的。这是其他6种模式的组合。实际上,这实现了具有良好抽象实体的线程池。
答案 4 :(得分:0)
看看commons ThreadPool。 Altough Java - 它是开源的,您可以查看代码并轻松移植到C ++