WaitForMultipleObjects alternative with std::thread?

WaitForMultipleObjects alternative with std::thread?

本文关键字:thread std alternative with WaitForMultipleObjects      更新时间:2023-10-16

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

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

有什么方法可以通过std :: thread?

实现相同的效果

据我所知,标准库中没有什么可以支持这种性质的等待。标准库建立在基础操作系统线程支持的顶部。必要时,标准库只能提供最低的公共分母功能。这意味着它无法包装Win32线程库提供的一些更丰富的功能。

只需使用 std::condition_variable,然后在完成之前让您的线程fire notify_all()notify_one()

然后做cv.wait()您想要WaitForMultipleObjects()调用的地方。

这是一个示例,说明如何使用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 = waitForFirst(std::begin(futures), std::end(futures));

参见实时示例

尝试ASYNC 组成,这是N3428 C 标准建议的参考实现。

本文在此之前很重要:

损坏的诺言–C 0x期货

以一种不可支配的方式,您还可以调用std :: thread :: bative_handle()与返回一起使用 WaitForMultipleObjects

有点迟到,但这是一个示例(适用于Windows):

#include <Windows.h>
#include <thread>


std::shared_ptr<bool> val1 = std::make_shared<bool>(0);
std::shared_ptr<bool> val2 = std::make_shared<bool>(0);
void thread(std::shared_ptr<bool> val) {
    *val = true;
    OutputDebugString(L"nnthreadnn");
    return;
}
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE useless, PWSTR cmdLine, int nCmdShow) {

    *val1 = false;
    *val2 = false;
    std::thread tr1(thread, val1);
    std::thread tr2(thread, val2);
    tr1.detach();
    tr2.detach();
    while (!(*val1) || !(*val2)) {
        OutputDebugString(L"WAITn");
    };
    OutputDebugString(L"nnFinishednn");

    return 0;
}

您想要的是相当于busost :: thread_group的等效内容。

不存在,但是您可以编写该功能:std :: vector and std :: for_each呼叫join()/waitforsingleobject在每个元素上,或者当然要搜索像cppthreadpool一样执行的第三方