Why do I need to join the stream, 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 should I call t.join() after calling f.get() ? I thought f.get() would block the main thread until it could get the result, and that would mean that the thread was already completed.

+5
source share
2 answers

Because even after the thread completes execution, it still connects. You can call detach to do independent execution. In this case, you can use the set_value_at_thread_exit member promise to reduce the chance that main will complete before the 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

+2
source

I believe that the rationale for threads is simply that you either explicitly join them or explicitly disable them, but if the thread object is destroyed before this happens, you are likely to have a problem with your design. The solution was not to assume that you want to separate it or join it when the destructor is called, because in most cases this is a bad assumption.

In addition, as far as your case is concerned, it does not matter what the future depends on. The requirements for the thread object are not affected by how it launches the future, they remain unchanged.

Please note that in your case, since you no longer care about the stream, you can simply disconnect it.

+2
source

Source: https://habr.com/ru/post/1238925/


All Articles