Reputation: 162
Having such simple code:
void func(std::promise<int>* p) {
int a = 10, b = 5;
int result = a + b;
std::cout << "From inside the Thread...." << std::endl;
p->set_value(result);
}
int FP_main() {
std::promise<int> p;
std::future<int> f = p.get_future();
std::thread th(func, &p);
int ret = f.get();
std::cout << "returned val: " << ret << std::endl;
th.join();
return 0;
}
Why do we need the join
function call if there is get
call just 2 lines above? Isn't the get
function waiting for a thread to finish?
Upvotes: 4
Views: 1097
Reputation: 24738
Why do we need the
join
function call if there isget
call just 2 lines above?
Destroying a joinable std::thread
object results in std::terminate()
being called. This is regardless of whether or not its associated thread is done. So, the call to get()
on the future is irrelevant when it comes to having to call join()
on a joinable std::thread
object before it is destroyed.
If you don't want to have to call join()
, then you could just call detach()
on the std::thread
somewhere before its destruction. This way, the thread won't be joinable at the moment of destruction.
Upvotes: 1
Reputation: 33506
Because the thread is not the promise.
Promise is finished, but thread is not.
p->set_value(result);
// ...
// HERE
// ...
}
That are the last lines of func
. The thread will now do its cleanups, will call destructors, etc. All while the promise is finished. Of couse, in 'HERE' the thread may a ton of other work - you can write a 1-hour long task in HERE to keep the thread alive and it will have nothing to do with the promise.
That's probably all clear already.
The last interesting bit is here:
int FP_main() {
//...
std::thread th(func, &p);
//...
th.join();
return 0;
}
The 'th' is a local variable. When the main() returns, the destructor of th
will be invoked. And that destructor throws an exception when the thread in question is not finished and not join'ed.
If the thread were busy after setting the value of the promise (i.e. doing destructors, or doing some 1-hour-long job), the std::thread's destructor invoked by } after return 0; would throw and crash the program. Hence, you need to join.
Upvotes: 4