3

我目前有一个具有大量线程的应用程序,这使得应用程序非常大。每个线程都是长时间运行的,基本上是轮询新电子邮件然后处理它们的无限循环。每个线程都保持一个 SSL 连接,这就是线程对应用程序很好的原因。

我想使用线程池。最简单的方法是固定线程数,然后每个线程添加 10 个用户,但即使在这一点上,它似乎也没有像 1 个用户/线程那样均匀地平衡工作,因为每个循环的处理时间都相当长。另外,这实际上不是线程池。

我的问题是——这里正确的设计模式是什么(因为它肯定比我上面写的更智能),是否有一个 C++ 库可以很好地处理这个问题?将我指向 Java 实用程序也会很有帮助,因为根据我的经验,从 Java 实用程序中制定设计模式非常容易。

4

5 回答 5

3

一个用户/线程可能是一个很好的起点。任何阻塞或可能被阻塞的东西都需要在自己的线程中运行,以避免阻塞或被其他正在执行的代码阻塞。如果电子邮件的实际处理要直接运行,则可以将其放置在“可运行”中,使用 Java 术语,并提交到线程池。Java 术语是ThreadPoolExecutor,自己编写一个简单的也不会那么难。您希望每个可能的 CPU 内核都有一个线程,以便从您的计算机中获得最大的工作量。

如果每封电子邮件的工作量不是很大,那么跳过线程池并只在阅读器线程上完成工作可能会更简单、更快。你已经支付了运行它的成本,你也可以尽你所能地完成所有工作。

在另一个极端,如果处理电子邮件涉及阻止或被阻止,您可能希望为每封电子邮件启动一个新线程。您最终可能会使用很多线程,但它会从您的计算机中获得最大的工作量。您不希望在 CPU 使用率仅为 5% 的情况下落后于电子邮件。

于 2012-06-25T17:35:35.887 回答
1

我会在后端放置一个 BlockingDeque 和一个线程池消费者。这将电子邮件生产者与消费者分离,并允许您在后端汇集消费者。看看这个:

生产者消费者示例

于 2012-06-25T14:49:27.290 回答
1

有许多模式可以解决问题,但做出决定的关键是了解模式的后果。ACE 网站上有一些关于一些可能适合的并发模式的论文,例如Active ObjectProactorReactor。这些示例是 C++,但如果您追求自己的实现,这些图表和描述会很有帮助。

摄者可以提供一个优雅的解决方案或作为另一种模式的基础。对于 C++ 实现,我会推荐这个boost::asio库:

  • 相当完善的文档和示例。
  • SSL 支持。
  • HTTP Server 3示例展示了如何使用线程boost::asio池。

如果不想依赖boost,那么这里asio的库也是单独打包的。有关更多模式和信息,请考虑本书。

于 2012-06-25T16:30:44.880 回答
0

我并不真正理解您的陈述“似乎没有像 1 个用户/线程那样均匀地平衡工作,因为每个循环的处理时间都相当长”。

无论如何,Active Object模式在您的情况下可能是一种优雅的模式。这是其他 6 种模式的组合。实际上,这实现了一个具有良好抽象实体的线程池。

于 2012-06-25T14:50:08.563 回答
0

看看commons ThreadPool。Altough Java - 它是开源的,您可以查看代码并轻松移植到 C++

于 2012-06-25T15:15:14.937 回答