主线程等待 std::async 完成[重复]

Posted

技术标签:

【中文标题】主线程等待 std::async 完成[重复]【英文标题】:main thread waits for std::async to complete [duplicate] 【发布时间】:2018-02-02 03:42:34 【问题描述】:

我正在使用std::async 创建一个线程,我希望这个新线程应该单独执行并且主线程不应该等待它。但是在这里,当我调用 std::async 时,会创建一个新线程,但主线程正在等待fun() 的完成。我希望主线程并行执行而不等待fun() 完成。我该怎么做?

#include <iostream>
#include <windows.h>
#include <future>
using namespace std;



void printid()

   cout << "Thread id is:" << this_thread::get_id() << endl;


void fun(void *obj)


   cout<<"Entry"<<endl;
   printid();
   Sleep(10000);
   cout<<"Exit"<<endl;



int main()

    cout<<"Hello"<<endl;
    printid();
    std::async(std::launch::async, fun, nullptr);
    cout << "After call" << endl;

我得到了输出:

Hello
Thread id is:22832
Entry
Thread id is:13156
Exit
After call

【问题讨论】:

【参考方案1】:

std::async 返回并使用std::launch::async 策略启动的std::future 对象,在销毁时阻塞,直到启动的任务完成。

由于您没有将返回的std::future 存储在变量中,它会在语句末尾用std::async 销毁,因此,main 在任务完成之前无法继续。

如果您存储std::future 对象,它的生命周期将延长到main 的末尾,您将获得您想要的行为。

int main()

    ...
    auto fut = std::async(std::launch::async, fun, nullptr);
    ...

【讨论】:

【参考方案2】:
std::async(std::launch::async, fun, nullptr);

对返回的std::future 不做任何事情,让它被销毁。这是一个问题,因为std::future's destructor 可能会阻塞并等待线程完成。

解决办法是在std::future 上保持一段时间,等你做完其他事情后让它销毁。

auto locallyScopedVariable = std::async(std::launch::async, fun, nullptr);

locallyScopedVariable 将在main 结束时超出范围,然后阻塞直到完成。

请注意,这仍然可能无法达到您想要的效果。主线程可以立即将处理器让给新线程,并允许新线程在返回控制之前运行完成。可以更正代码,但仍然会导致输出不正确的版本。

【讨论】:

【参考方案3】:

(1) 在多线程程序测试中,使用互斥锁保护共享资源(本例中为cout)不被不同线程同时调用。 (2) 主要检查future是否准备好,你也可以做一个超时。

void print_id() 

    lock_guard<mutex> locker(mutex_);
    cout << "Thread id is:" << this_thread::get_id() << endl;


void print( string str) 

    lock_guard<mutex> locker(mutex_);
    cout << str << '\n';
   

bool fun(void *obj)

   print("Entry");
   printid();
   Sleep(10000);
   print("Exit");
   return true;



int main()

    print("Hello");
    printid();
    std::future<bool> fut = std::async(std::launch::async, fun,nullptr);
    while(!fut->_Is_ready() )
    
     
    cout << "After call" << endl;

【讨论】:

while(!fut-&gt;_Is_ready() ) 强制行为与提问者不想要的行为相同。主线程基本上被阻塞等待线程完成。

以上是关于主线程等待 std::async 完成[重复]的主要内容,如果未能解决你的问题,请参考以下文章

指定线程的 std::async 模拟

主线程是不是在阻塞线程上运行?

死锁使用 std::mutex 保护多线程中的 cout

如何使“主线程”等待“子线程”执行结束后再继续执行

在主窗体关闭并且不等待线程完成后让线程运行

C++11 多线程std:: async与std::thread的区别