主线程等待 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->_Is_ready() )
强制行为与提问者不想要的行为相同。主线程基本上被阻塞等待线程完成。以上是关于主线程等待 std::async 完成[重复]的主要内容,如果未能解决你的问题,请参考以下文章