主线程等待std :: async完成

时间:2018-02-02 03:42:34

标签: c++ multithreading asynchronous stdasync

我使用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

3 个答案:

答案 0 :(得分:4)

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

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

如果存储std::future对象,其生命周期将延长至main的末尾,您将获得所需的行为。

int main()
{
    ...
    auto fut = std::async(std::launch::async, fun, nullptr);
    ...
}

答案 1 :(得分: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末尾的范围,然后阻止直至完成。

请注意,这仍然可能无法满足您的需求。主线程可以立即将处理器提供给新线程,并允许新线程在返回控制之前运行完成。代码可以更正,但仍会导致输出错误的版本。

答案 2 :(得分:0)

(1)在多线程程序测试中,保护共享资源(在这种情况下为cout)不使用互斥锁同时从不同的线程调用。 (2)检查主要的未来是否准备就绪,也可以暂停。

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