使用std :: thread的WaitForMultipleObjects替代方案?

时间:2014-01-31 08:31:25

标签: c++ multithreading stl

我的问题是我有多个线程,它们存储在某个容器中,我需要知道某个位置的线程何时完成。 在Windows上,我会做类似的事情:

HANDLE handles[3];
//handles were initialized
DWORD finishingThread = WaitForMultipleObjects(3, handles, false, INFINITE)

有没有办法用std :: thread实现相同的效果?

5 个答案:

答案 0 :(得分:6)

据我所知,标准库中没有任何内容支持等待这种性质。标准库建立在底层操作系统线程支持之上。必要时,标准库只能提供最低的公分母功能。这意味着它无法包装Win32线程库提供的一些更丰富的功能。

答案 1 :(得分:3)

只需使用std::condition_variable,即可让线程在完成之前触发notify_all()notify_one()

然后执行您需要cv.wait()电话的WaitForMultipleObjects()

答案 2 :(得分:2)

这是一个如何使用std::threadstd::future来实现相同效果的示例,如果您愿意在轮询线程准备就绪时让主线程处于休眠状态(或者您可以使用专用线程)线程处理等待)。

考虑这个函数,将一系列迭代器带到std::future的容器,该容器将阻塞,直到至少完成一个任务:

const int TIME_BETWEEN_POLLS_MS = 50;

// Wait (sleep) between polls until a task is finished then return iterator to future.
template <typename Iterator>
Iterator waitForFirst(Iterator first, Iterator last) {
    auto it = first;
    auto status = std::future_status::timeout;
    while (status != std::future_status::ready) {
        if (++it == last) { // Rotate in range.
            it = first;
        }
        status = it->wait_for(std::chrono::milliseconds(TIME_BETWEEN_POLLS_MS));
    }
    return it;
}

现在,如果你有一个期货容器(std::future)与在不同线程上运行的任务的返回值相关联,你可以简单地使用函数waitForFirst来获得未来的迭代器首先得到它的结果。

    // Lets say you have a vector of futures, e.g.
    std::vector<std::future<std::thread::id>> futures;

    /* Push futures to vector... */

    // Block until first task is finished.
    // 'it' is iterator to future associated with result.
    auto it = finishingThread(std::begin(futures), std::end(futures));

请参阅live example

答案 3 :(得分:1)

尝试Async++ Composition,这是N3428 C ++标准提案的参考实现。

在此之前,本文是相关的:

Broken promises–C++0x futures

以不可移植的方式,您也可以致电std::thread::native_handle()使用WaitForMultipleObjects返回。

答案 4 :(得分:-1)

你想要的是与boost :: thread_group相同的东西。

不存在,但您可以编写该功能:std :: vector和std :: for_each在每个元素上调用join()/ WaitForSingleObject,或者当然搜索像{一样执行相同操作的第三方{3}}