4

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 但它指出一个任务应该需要一两秒才能有效。我不需要任何花哨的调度、优先级等。我只想消除重复构建和销毁线程的开销。

4

1 回答 1

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();
    });
于 2013-04-09T14:35:12.610 回答