Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do I need to join a thread even if I use std::future::get?

void
set_string(std::promise<std::string>& p)
{
  p.set_value("set from thread");
}

int
main()
{
  std::promise<std::string> p;
  std::future<std::string> f = p.get_future();
  std::thread t(&set_string, std::ref(p));
  std::cout << f.get() << std::endl;
  t.join();
}

Why do I need to call t.join() after I call f.get()? I thought that f.get() will block the main thread until it can get the result and that would mean that the thread has already finished.

like image 836
Maik Klein Avatar asked Sep 25 '22 21:09

Maik Klein


2 Answers

Because even after thread finishes execution it is still joinable. You can call detach to allow independend execution. In this case you might want to use set_value_at_thread_exit member of promise to lessen chance that main finishes before thread:

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

void set_string(std::promise<std::string>& p)
{
  p.set_value_at_thread_exit("set from thread");
}

int main()
{
  std::promise<std::string> p;
  std::future<std::string> f = p.get_future();
  std::thread(&set_string, std::ref(p)).detach();
  std::cout << f.get() << std::endl;
}

http://coliru.stacked-crooked.com/a/1647ffc41e30e5fb

like image 56
Revolver_Ocelot Avatar answered Oct 03 '22 17:10

Revolver_Ocelot


I believe the rationale for threads is simply that you either explicitly join them or that you explicitly detach them, but if a thread object gets destroyed before either happened, you probably have a problem with your design. The decision was not to assume you want to detach it or join it when the destructor is called, because either one is a bad guess in most situations.

Further, concerning your case, it doesn't matter where the future is set from. The requirements for the thread object are not touched by how it triggers the future, they stay the same.

Note that in your case, since you don't care about the thread any longer, you could simply detach it.

like image 31
Ulrich Eckhardt Avatar answered Oct 03 '22 18:10

Ulrich Eckhardt