WaitForMultipleObjects alternative with std::thread? WaitForMultipleObjects alternative with std::thread? multithreading multithreading

WaitForMultipleObjects alternative with std::thread?


To the very best of my knowledge, there is nothing in the standard library that supports a wait of that nature. The standard library is built on top of the underlying operating system threading support. By necessity the standard library can only offer lowest common denominator functionality. Which means that it is not able to wrap some of the richer functionality offered by the Win32 threading library.


Just use a std::condition_variable and have your threads fire notify_all() or notify_one() right before they finish.

Then do cv.wait() where you want your WaitForMultipleObjects() call.


Here's an example of how you can achieve the same effect using std::thread and std::future if you are willing to let the main thread sleep while polling the readiness of the threads (alternatively you could let a dedicated thread handle the waiting).

Consider this function, taking a range of iterators to a container of std::future, which will block until at least one task is finished:

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;}

Now if you have a container of futures (std::future) associated with the return values of your tasks running on separate threads, you can simply use the function waitForFirst to get an iterator to the future that gets its result first.

    // 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));

See live example