简体   繁体   中英

How to get a return value from a thread?

Lets say a function,

int fun(){
    static int a = 10;
    a = a+1;
    return a;
}

The above function is returning a integer value,

//Without thread obtaining return value
#include<iostream>
int main()
{
    int var = 0;
    var = fun();
    std::cout << "The value " << value << std::endl;
    return 0;
}

Now is there any possible way to get the returned value when invoked by C++11 thread,

//Using thread
#include<iostream>
#include<thread>
int main()
{
    std::thread t1(fun);//Invoking thread
    //How to obtain the return value of the thread ?
    return 0;
}

Thanks!

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 (ie, 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, ie, 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

You can use async , a promised future (pun intended) or packaged task.

// future from a packaged_task
std::packaged_task<int()> task(fun); // wrap the function
std::future<int> f1 = task.get_future();  // get a future
std::thread(std::move(task)).detach(); // launch on a thread

// future from an async()
std::future<int> f2 = std::async(std::launch::async, fun);

// future from a promise
std::promise<int> p;
std::future<int> f3 = p.get_future();
std::thread( [](std::promise<int>& p){ p.set_value(fun()); },
             std::ref(p) ).detach();


std::cout << "Waiting...";
f1.wait();
f2.wait();
f3.wait();
std::cout << "Done!\nResults are: "
          << f1.get() << ' ' << f2.get() << ' ' << f3.get() << '\n';

No, std::thread is just a simple C++ wrapper that allows to start an OS thread of execution and wait until it's done.

To share the return value with the calling thread, you can either manually provide the thread with a shared state, or use a higher-level facilities like packaged_task , future etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM