For obtaining return values form functions that are meant to be run in background, you may want to consider std::future
instead of directly creating an std::thread
object. You can use the std::async()
function template to start an asynchronous task. It returns an std::future
object that will eventually contain the return value of the function passed:
auto res = std::async(fun);
// ... optionally do something else
std::cout << res.get() << '\n';
That is, you create an std::future<int>
by calling std::async(func)
. Then, when you need fun()
's return value, you simply call the get()
member function on the future. If the future isn't ready yet (i.e., if it doesn't have the result yet), then the thread will block until it is.
Why not directly use std::thread
The problem with std::thread
is that it doesn't provide a direct mechanism for transferring the return value of the callable passed at its construction. For example, suppose you want to start a new thread with std::thread
to calculate the sum of two integers with the following function:
int sum(int a, int b) { return a + b; }
What you would probably try is:
std::thread th_sum(sum, 1, 2);
// ... optionally do something else
th_sum.join();
// calculation is finished, but where is the result?
The thread represented by th_sum
does calculate the sum of 1 and 2. However, you don't get sum()
's return value, i.e., the result, from the associated std::thread
object.
Instead, what you could do to handle this deficiency is, for example, to create a wrapper function for sum()
that has an out parameter for the result instead of returning it:
void sum_outparam(int a, int b, int& res) { res = sum(a, b); }
Then, you can start a new thread for running this wrapper function and with help of std::ref()
you will obtain the result in res
:
int res;
std::thread th_sum(sum_outparam, 1, 2, std::ref(res));
// ... optionally do something else
th_sum.join();
// now, res contains the result