如何根据程序的计算需求自动将线程添加到池中?

Mat*_*ers 7 c++ multithreading threadpool

我们有一个C++程序,根据用户配置的方式,可能是CPU绑定或IO绑定.为了与程序配置松散耦合,我希望我的线程池能够在程序受益于更多线程(即CPU绑定)时自动实现.如果它意识到它是I/O限制并减少了工作人员数量会很好,但这只会是一个奖励(即我会对自动增长而没有自动收缩的东西感到满意).

我们使用Boost,所以如果有什么东西可以帮助我们使用它.我意识到任何解决方案可能都是特定于平台的,所以我们主要对Windows和Linux感兴趣,对OS X或任何其他*nix有兴趣.

Com*_*czy 4

简短回答:对 CPU 密集型操作和 IO 使用不同的固定大小线程池。除了池大小之外,活动线程数量的进一步调节将由同步工作流程的计算机和 IO 步骤的有界缓冲区(生产者/消费者)完成。

对于计算和数据密集型问题,其中瓶颈是不同资源之间的移动目标(例如 CPU 与 IO),明确区分线程和线程可能很有用,特别是作为第一个近似值:

  • 为使用更多 CPU 周期而创建的线程(“CPU 线程”)
  • 为处理异步 IO 操作而创建的线程(“IO 线程”)

更一般地说,线程应该根据它们所需的资源类型进行隔离。目的应该是确保单个线程不会使用多个资源(例如,避免在同一线程中读取数据和处理数据之间进行切换)。当一个线程使用多个资源时,它应该被分割,并且两个结果线程应该通过有界缓冲区同步。

通常,CPU 线程的数量应该与系统上所有可用内核的指令管道饱和所需的数量完全相同。为了确保这一点,只需拥有一个“CPU 线程池”,其中包含仅专用于计算工作的线程数。那将是boost::或者std::thread::hardware_concurrency()如果那可以被信任。当应用程序需要较少的线程时,CPU 线程池中就会有未使用的线程。当需要更多时,工作就会排队。您可以使用 c++11 来代替“CPU 线程池”,std::async但您需要通过选择同步工具(例如计数信号量)来实现线程限制机制。

除了“CPU线程池”之外,还可以有另一个线程池(或其他几个线程池)专门用于异步IO操作。在您的情况下,IO 资源争用似乎是一个潜在的问题。如果是这种情况(例如本地硬盘驱动器),则应仔细控制最大线程数(例如本地硬盘驱动器上最多 2 个读取线程和 2 个写入线程)。这在概念上与 CPU 线程相同,您应该有一个固定大小的线程池用于读取,另一个用于写入。不幸的是,可能没有任何好的原语可用于决定这些线程池的大小(如果您的 IO 模式非常规则,那么测量可能很简单)。如果资源争用不是问题(例如 NAS 或小型 HTTP 请求),那么 boost::asioc++11std::async可能是比线程池更好的选择;在这种情况下,线程限制可以完全留给有界缓冲区。