从std :: thread获取返回码?

时间:2012-09-07 14:23:17

标签: c++ multithreading c++11 return-value

  

可能重复:
  C++: Simple return value from std::thread?

无论如何从std :: thread获取返回码?我有一个函数返回一个整数,我希望能够在线程执行完毕后从函数中获取返回代码。

4 个答案:

答案 0 :(得分:18)

不,这不是std::thread的用途。

相反,请使用async获取future

#include <future>

int myfun(double, char, bool);

auto f = std::async(myfun, arg1, arg2, arg3);  // f is a std::future<int>

// ...

int res = f.get();

您可以使用f的{​​{3}}成员函数(零超时)来查看结果是否准备就绪。

答案 1 :(得分:14)

Kerrek SB对他的答案是正确的,但我建议添加另一个例子(他建议应该是答案,所以在这里)。

我最近发现至少在VC11 std::async will not release all the resources of the thread until the end of the application中,可能导致内存泄漏误报(如果您正在监视它们,例如Visual Leak Detector)。

这里我的意思是,在大多数基本应用程序中,不值得查看这个答案的其余部分,但如果像我一样你需要检查内存泄漏并且不能让误报,就像在main函数结束时未发布的静态数据一样。如果是你的情况,那么这可能有所帮助。

std::async默认不保证在单独的线程中运行,只有当您使用std::launch::async作为第一个参数时才会这样做。否则,实现决定做什么,这就是为什么VC11实现将使用新的Microsoft并发运行时任务管理器来管理提供的功能作为任务池中推送的任务,这意味着线程在透明的情况下维护和管理办法。有一些方法可以明确地终止任务管理器,但这也是特定于平台的,使得异步是一个糟糕的选择,当你想要完全1)确保启动一个线程和2)稍后得到一个结果3)确保在得到结果后线程完全释放


完全相同的替代方法是将std::packaged_taskstd::threadstd::future结合使用。它的完成方式与使用std::async几乎相似,只是更冗长一点(这意味着如果需要,可以在自定义模板函数中对其进行概括)。

#include <packaged_task>
#include <thread>

int myfun(double, char, bool);

std::packaged_task<int(double, char, bool)> task(myfun, arg1, arg2, arg3); 

auto f = task.get_future();  // f is a std::future<int> 

首先我们创建一个任务,基本上是一个包含函数和将来与std::promise相关联的对象。 std::packaged_task的工作方式大致类似于std::function的增强版:

现在我们需要明确地执行线程:

std::thread thread(std::move(task));

thread.detach();

此举是必要的,因为std::packaged_task不可复制。仅当您只想使用将来进行同步时才需要分离线程 - 否则您将需要显式加入线程。如果你没有,当调用线程的析构函数时,它只会调用std::terminate()

// ...

int res = f.get(); // Synchronization and retrieval.

答案 2 :(得分:13)

正如其他人所建议的那样,<future>中的设施可用于此目的。但是我反对回答

  

不,您不能使用std::thread

执行此操作

以下是使用std::thread执行所需操作的一种方法。这绝不是唯一的方法:

#include <thread>
#include <iostream>

int func(int x)
{
    return x+1;
}

int main()
{
    int i;
    std::thread t([&] {i = func(2);});
    t.join();
    std::cout << i << '\n';
}

这将便于输出:

3

答案 3 :(得分:3)

以下是使用packaged_task的示例:

#include <future>
#include <iostream>

void task_waiter(std::future<int>&& f) {
    std::future<int> ft = std::move(f);
    int result = ft.get();
    std::cout << result << '\n';
}

int the_task() {
    return 17;
}

int main() {
    std::packaged_task<int()> task(the_task);
    std::thread thr(task_waiter, task.get_future());
    task();
    thr.join();
    return 0;
}