Home > Mobile >  c 11 promise object gets invalid, but its future object neither returns value nor throw exception
c 11 promise object gets invalid, but its future object neither returns value nor throw exception

Time:06-25

I've got this test code to see, if a promise object is out of lifecycle, what happen to its future object:

#include <chrono>
#include <future>
#include <iostream>
#include <thread>
using namespace std;

void getValue(future<int>& future) {
    cout << "sub process 1 \n";
    try {
        cout << "sub process 2 \n";
        int value = future.get();
        cout << "sub process 3\n";
        cout << value << endl;
    } catch (future_error &e) {
        cerr << e.code() << '\n' << e.what() << endl;
    } catch (exception e) {
        cerr << e.what() << endl;
    }
    cout << "sub process 4\n";
}
int main() {
    thread t;
    {
        promise<int> plocal;
        future<int> flocal = plocal.get_future();
        t = thread(getValue, ref(flocal));
    }
    t.join();
    return 0;
}

I expect that in getValue function, it either prints future::get result, or throws out runtime exception and prints exception info, because plocal has been destructed in "main".

Acturally, this program prints:

sub process 1
sub process 2

and ends.

CodePudding user response:

Your problem is not about std::promise or std::future behavior.

You simply cause a data race (and consequently undefined behavior) by passing the flocal object by-reference to the thread, accessing it in the thread, but also destroying it in the main thread without any synchronization.

This doesn't work no matter what type or kind of object flocal is.

Pass the std::future by-value via std::move:

void getValue(future<int> future)

/*...*/

t = thread(getValue, std::move(flocal));

With this change the destructor of std::promise will store a std::future_error exception in the shared state and get on the future in the thread will receive and throw it.


If you pass something with std::ref to a thread you always have to make sure that the referenced object outlives the thread or you need to make sure that there is some synchronization mechanism to determine when the main thread may destroy the object.

  • Related