从std :: thread获取返回码?

who*_*osy 8 c++ multithreading return-value c++11

可能重复:
C++:std :: thread的简单返回值?

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

Ker*_* SB 19

不,那不是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();
Run Code Online (Sandbox Code Playgroud)

您可以使用(零超时)wait_for成员函数f来查看结果是否准备就绪.

  • @Klaim:我不太了解`packaged_task`,也不知道它的习语.请把它作为答案发布; 这将是为了每个人的利益. (4认同)
  • @AnthonyWilliams:哦,我没有意识到,你是我刚买的那本书!这真让人兴奋. (3认同)

Kla*_*aim 14

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

我最近发现,至少在VC11中,std::async在应用程序结束之前不会释放线程的所有资源,从而可能导致内存泄漏误报(如果您正在监视它们,例如Visual Leak Detector).

在这里,我的意思是,在大多数基本应用程序中,不值得查看其余的答案,但如果像我一样,你需要检查内存泄漏,并且不能让误报,就像静态数据没有在最后发布主功能.如果是你的情况,那么这可能会有所帮助.

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


完全相同的替代方案是使用std::packaged_taskstd::thread结合使用std::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> 
Run Code Online (Sandbox Code Playgroud)

首先,我们创建一个任务,基本上是一个包含函数和std::promise将来与之关联的对象.std::packaged_task作品大多像增强版std::function:

现在我们需要显式执行该线程:

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

thread.detach();
Run Code Online (Sandbox Code Playgroud)

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

// ...

int res = f.get(); // Synchronization and retrieval.
Run Code Online (Sandbox Code Playgroud)


How*_*ant 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';
}
Run Code Online (Sandbox Code Playgroud)

这将可以输出:

3
Run Code Online (Sandbox Code Playgroud)