C++11 线程队列

3

我希望能够启动一大堆线程:

futures_que< std::future< ret_value > > fq;

for ( auto a: some_very_large_container )
    fq.push_back( std::async( std::launch::async, some_computationally_expensive_function, a));

std::vector< ret_value > values;
for ( auto f: fq ) {
    f.wait();
    values.push_back( f.get() );
}

然而,如果我这样幼稚地做(例如使用futures_que作为std::vector),它们将全部同时运行,效率并不高。如何做类似的事情:启动所有线程,但仅运行几个(例如计算机上的核心数),当一个线程死亡时,启动另一个线程。

3
它被称为线程池。 - Bryan Chen
@BryanChen 不完全是。经典的线程池有固定数量的线程在运行,并使用消息传递来请求和分配新任务。我可以接受线程本身被销毁/创建。我只想要一个固定数量的线程。这是一个微妙的区别(我不必担心用我的方式创建消息传递框架)。 - Andrew Spott
1
创建/销毁线程和运行永久线程只是线程池的两种不同实现。如果您的任务很小且线程创建频繁,则线程创建非常昂贵。您需要的肯定是一个线程池。消息传递框架???有许多种“消息传递框架”可用于线程池,但一种非常简单的实现称为“阻塞队列”。它非常容易实现。 - pasztorpisti
你是在问如何编写一个使用计数器变量的for循环,而不是相对较新的容器语法吗? :) - Kenny Ostrom
C#会为您解决这个问题;) 在C++中,我认为您无法进行fire-and-forget。您将不得不实现一个控制器来管理线程。您可能可以使用when_any来知道何时启动新线程。 - JHBonarius
2个回答

1

wait_any()并没有在那篇论文的文本搜索中出现。你是不是指的是when_any() - Andrew Spott
此外,when_any() 似乎做了我不想要的事情... 它等待所有任务完成,但不区分正在运行的任务。 - Andrew Spott
你是指 when_any() 吗?啊,没错,when_any() 可以区分吗? - Akira Takahashi

0
将“std::launch::async | std::launch::deferred”作为参数传递给“std::async”。
std::async(std::launch::async | std::launch::deferred, some_computationally_expensive_function)

在Visual Studio 2013中行得通,但自从Visual Studio 2015以后就不行了。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接