用线程池替换许多std :: async调用

时间:2013-04-09 14:05:59

标签: c++ multithreading threadpool

我有一个多次调用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 但它指出任务应该花费一到两秒才能有效。我不需要任何花哨的调度,优先级等。我只想删除重复构造和破坏线程的开销。

1 个答案:

答案 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();
    });