我有一个多次调用std::async
的程序。执行的任务是合理的短(每个几百毫秒)。我认为线程创建有很大的开销,我想知道我是否可以以某种方式避免这种情况。枚举作业的代码运行速度比处理作业要快得多。因此,我已经有了一种集合。它是这样的。我创建了一个'工作槽'数组:
template <typename T>
struct job {
std::future <void> fut;
std::vector <T*> *result;
bool inUse;
}
在并行代码启动之前,我初始化作业槽数组,只创建一次结果向量。然后,每次作业枚举代码枚举作业时,它都会查找未使用的作业槽。如果有一个空闲插槽,它将启动(使用std :: async)一个新作业,将未来移动到插槽。作业运行并填充结果向量。如果没有空闲插槽,则代码检查插槽中的任何期货是否准备就绪。如果是,则处理结果向量,然后使用该槽。如果没有,它会等待几毫秒。此代码运行得非常好,并且可以精确地扩展到可用的处理器数量。我了解到每次调用std::async
都会创建一个新线程,实际上,我可以看到进程ID滚动。我想删除这个开销,在开始时一劳永逸地创建线程。怎么办?
我找到了这个线程池实现 https://code.google.com/p/cppthreadpool/downloads/list 但它指出任务应该花费一到两秒才能有效。我不需要任何花哨的调度,优先级等。我只想删除重复构造和破坏线程的开销。
答案 0 :(得分:0)
我运行了一个使用std :: async创建任务的测试程序,发现许多任务都是由同一个线程运行的!实际上我看到2个线程运行了25个异步任务。所以看起来标准库已经做了一些线程池。
std::vector<std::future<void>> futures;
for (int i = 0; i < 25; ++i)
{
auto fut = std::async([]
{
std::cout << std::this_thread::get_id() <<std::endl;
});
futures.push_back(std::move(fut));
}
std::for_each(futures.begin(), futures.end(), [](std::future<void> & fut)
{
fut.wait();
});