Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何根据程序的计算需要自动向池中添加线程? 我们有一个C++程序,它取决于用户配置它的方式,可以是CPU绑定的或IO绑定的。为了实现与程序配置的松耦合,我想让线程池自动实现程序何时能从更多线程中获益(即CPU受限)。如果它意识到它是I/O绑定的,并且减少了工作人员的数量,那将是一件好事,但这只是一种奖励(也就是说,我很高兴看到一些东西能够自动增长,而不会自动收缩)_C++_Multithreading_Threadpool - Fatal编程技术网

如何根据程序的计算需要自动向池中添加线程? 我们有一个C++程序,它取决于用户配置它的方式,可以是CPU绑定的或IO绑定的。为了实现与程序配置的松耦合,我想让线程池自动实现程序何时能从更多线程中获益(即CPU受限)。如果它意识到它是I/O绑定的,并且减少了工作人员的数量,那将是一件好事,但这只是一种奖励(也就是说,我很高兴看到一些东西能够自动增长,而不会自动收缩)

如何根据程序的计算需要自动向池中添加线程? 我们有一个C++程序,它取决于用户配置它的方式,可以是CPU绑定的或IO绑定的。为了实现与程序配置的松耦合,我想让线程池自动实现程序何时能从更多线程中获益(即CPU受限)。如果它意识到它是I/O绑定的,并且减少了工作人员的数量,那将是一件好事,但这只是一种奖励(也就是说,我很高兴看到一些东西能够自动增长,而不会自动收缩),c++,multithreading,threadpool,C++,Multithreading,Threadpool,我们使用Boost,所以如果有什么东西可以帮助我们,我们可以使用它。我意识到任何解决方案都可能是特定于平台的,因此我们主要对Windows和Linux感兴趣,对OS X或任何其他*nix感兴趣。简短回答:对于CPU密集型操作和IOs,使用不同的固定大小线程池。除了池大小之外,活动线程数量的进一步调节将由有界缓冲区(生产者/消费者)来完成,该缓冲区同步计算机和工作流的IO步骤 对于计算和数据密集型问题,瓶颈是不同资源(例如CPU与IO)之间的移动目标,明确区分线程和线程非常有用,尤其是作为第一近似

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

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

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

  • 为使用更多CPU周期而创建的线程(“CPU线程”)
  • 为处理异步IO操作而创建的线程(“IO线程”)
更一般地说,线程应该按照它们所需的资源类型进行隔离。目标应该是确保单个线程不会使用多个资源(例如,避免在同一线程中读取数据和处理数据之间切换)。当一个线程使用多个资源时,应该将其拆分,并通过一个有界缓冲区同步两个结果线程

通常,系统上所有可用内核的指令管道都应该完全满足CPU线程数的要求。为了确保这一点,只需拥有一个“CPU线程池”,其中包含的线程数量正好与只用于计算工作的线程数量相同。这将是
boost::
std::thread::hardware\u concurrency()
,如果可以信任的话。当应用程序需要更少的线程时,CPU线程池中将只存在未使用的线程。当需要更多时,工作将排队。您可以使用c++11
std::async
而不是“CPU线程池”,但您需要通过选择同步工具(例如计数信号量)实现线程节流机制


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

当您发现自己创建了大量线程以隐藏IO延迟时,是时候使用IOCP(或epoll,取决于操作系统)查看线程池了。请注意,boost::asio为这些事情提供了一个抽象层,而事实恰恰相反。我们的文件足够大,如果我们在读取时不进行任何密集处理,单个线程就可以使IO饱和。随着处理变得越来越复杂,事情可能会受到CPU的限制,然后从另一个线程(或更多线程)中获益。实际上,我们有一个信号处理算法,它确实需要额外的线程,但如果不使用,额外的线程实际上会花费我们时间,因为它们会导致文件(有时)被无序访问。嗨,来吧,谢谢你的回答。我不确定如何应用您的答案,但这可能是因为我没有足够清楚地解释我的用例。对于我来说,固定大小的线程池的问题是,我有固定数量(数千)的任务要排队,而线程池的任务是尽可能快地完成它们。当选项是线程将被I/O绑定时,最好只有1或2个线程,否则任务将在磁盘上无序,这会增加查找和缓冲成本。如果它们是CPU受限的,我会从更多线程中受益。因此,我在考虑更多类似于我的task dispatcher类的东西,从一个线程开始,然后相对于系统的CPU使用情况(除以物理内核的数量)监控我进程的CPU使用情况。当调度程序检测到我的进程正在使用几乎整个内核时,它将添加另一个线程。如果它开始使用两个完整的内核,它会添加另一个线程。以此类推,为了简单起见,我假设您有8个内核,最佳读取是在2个线程上。创建一个包含8个线程的“CPU线程池”和一个包含2个线程的“读取线程池”,中间有一个有边界的缓冲区。如果IO是瓶颈,那么两个读取线程都将被充分利用,有界缓冲区将大部分保持为空,一些CPU线程将处于空闲状态。如果CPU是瓶颈,那么所有CPU线程都将被充分利用,有界缓冲区将大部分保持满状态,读取线程将部分空闲。它是自我调节的,并始终围绕NEC进行优化