Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't future::wait() block

#include <iostream>
#include <string>
#include <thread>
#include <future>


int main()
{
    auto pms = std::promise<std::string>();
    auto ftr = pms.get_future();

    std::thread([&](){pms.set_value("hello world");});    
    ftr.wait();
    std::cout << ftr.get() << std::endl;

    return 0;
}

According to this link, std::future::wait blocks until the result becomes avaiable.

However, the code above can't print anything. Obviously the main thread has finished before the thread of pms.set_value finished.

Why doesn't ftr.wait() block?

like image 364
Yves Avatar asked Dec 16 '16 14:12

Yves


1 Answers

The problem is not that std::future::wait doesn't block. The real problem is that you have a race condition between the thread that you spawned, doing it's work, and the destruction of std::thread (temporary) object in the main thread.

Because of that, abort is called in the destructor of std::thread if the thread is still joinable.

Working code:

#include <iostream>
#include <string>
#include <thread>
#include <future>
#include <chrono>

int main()
{
    auto pms = std::promise<std::string>();
    auto ftr = pms.get_future();

    std::thread thread ([&](){pms.set_value("hello world");});    
    ftr.wait();
    std::cout << ftr.get() << std::endl;
    thread.join ();
    return 0;
}

Note, if you don't join the thread explicitly, you would still have the same race condition (since it's possible that main can do its work faster, than the thread can clean itself up.

Demo of working example: here.

like image 126
Algirdas Preidžius Avatar answered Sep 22 '22 23:09

Algirdas Preidžius