繁体   English   中英

如何从线程获取返回值?

[英]How to get a return value from a thread?

让我们说一个函数,

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

上面的函数返回一个整数值,

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

现在有没有办法在 C++11 线程调用时获取返回值,

//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;
}

谢谢!

为了从要在后台运行的函数获取返回值,您可能需要考虑std::future而不是直接创建std::thread对象。 您可以使用std::async()函数模板来启动异步任务。 它返回一个std::future对象,该对象最终将包含传递的函数的返回值:

auto res = std::async(fun);

// ... optionally do something else

std::cout << res.get() << '\n';

也就是说,您通过调用std::async(func)创建一个std::future<int> 然后,当您需要fun()的返回值时,您只需在未来调用get()成员函数。 如果未来还没有准备好(即,如果它还没有结果),那么线程将阻塞直到它准备好。


为什么不直接使用std::thread

std::thread的问题在于它没有提供直接机制来传输在其构造时传递的可调用对象的返回值。 例如,假设您想使用std::thread启动一个新线程,以使用以下函数计算两个整数的总和:

int sum(int a, int b) { return a + b; }

您可能会尝试的是:

std::thread th_sum(sum, 1, 2);

// ... optionally do something else

th_sum.join();
// calculation is finished, but where is the result?

th_sum表示的线程确实计算12的总和。 但是,您不会从关联的std::thread对象中获得sum()的返回值,即结果。

相反,你可以做的来处理这个缺陷,例如,为sum()创建一个包装函数,它有一个输出参数作为结果而不是返回它:

void sum_outparam(int a, int b, int& res) { res = sum(a, b); }

然后,您可以启动一个新线程来运行此包装函数,并在std::ref()帮助下获得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

您可以使用async 、承诺的未来(双关语)或打包任务。

// 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';

不, std::thread只是一个简单的 C++ 包装器,它允许启动 OS 执行线程并等待它完成。

要与调用线程共享返回值,您可以手动为线程提供共享状态,或者使用更高级的工具,如packaged_taskfuture等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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