我正在开发Windows C ++应用程序。我们使用boost库。我的应用程序中有一个操作,可以并行化以在多个线程上运行。每次线程数取决于操作参数,并且可以很大(比如50或70)。我不希望产生最大的线程,因为这是应用程序对其他操作无响应的风险(因为所有处理器都可以被占用)。我怎样才能确保我不会创造我描述的情况?如果一个线程池有帮助吗?如果是这样的话?
答案 0 :(得分:0)
只需创建一个线程池,例如我在这里发布的boost thread throwing exception "thread_resource_error: resource temporarily unavailable"
这里还有两种口味c++ work queues with blocking(一种使用Asio,一种只使用C ++ 11)
答案 1 :(得分:0)
现代硬件上的70个线程可以轻松处理,而不会对系统性能产生任何明显影响。线程创建时间,内存使用,调度和上下文切换开销可能是一个问题,但我们不知道在您的特定情况下它是否是一个问题。
如果不能创建70个线程,请考虑使用OpenMP(由所有主要编译器支持),因为它是一个非常简单且通常非常有效的解决方案:
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
do_task(i);
}
它在引擎盖下使用线程池。
如果出于某些原因无法接受OpenMP,则可以使用显式线程池。它可以是一个“自制的”线程池(不推荐),或来自@ sehe的答案,或者由操作系统提供的(如他的评论中提到的@Hans Passant),或者来自第三方库的一个(例如英特尔线程构建模块)。
是的,线程池可以帮助提高响应能力,但默认情况下,典型的线程池实现会创建线程数==逻辑CPU核心数。这意味着您的所有核心都可以忙于工作,这不一定是个问题。 Windows使用抢占式多线程。这意味着它可以处理的线程数远远大于CPU的数量,并且仍然具有响应能力。
线程池可以帮助,因为不可能同时执行比您拥有的逻辑CPU核心数更多的任务。由于更好地使用缓存和减少了上下文切换次数,线程池可以更高效。或者因为可以使用相同的线程多次执行您的操作。要确定您的表现。
答案 2 :(得分:-1)
您可以将std::async
与默认启动策略一起使用。但是,这与线程池不同。
在OpenMP中,您可以设置固定数量的线程,然后使用OpenMP task
。不幸的是,C ++ 11中没有这样的选项。标准说,可以推迟选择是在新线程中异步调用函数还是在相应wait
对象上调用get
或std::future
的线程中同步调用该函数,但是,然后,当选择异步调用时,仍然必须创建一个新线程。