为何std::async仍会阻塞主线程?代码示例与问题分析
为什么std::async会阻塞主线程?
示例代码
#include <iostream> #include <chrono> #include <thread> #include <future> #include <memory> using namespace std; void print2(){ std::chrono::milliseconds timespan(10000); std::this_thread::sleep_for(timespan); cout<<"async"<<endl; } void print(){ cout<<"bbb----"<<endl; } void test() { std::shared_ptr<void> _(nullptr, [&](...){ print(); }); auto a = async(print2); // 即使显式指定std::launch::async,结果一致 cout<<"end of test"<<endl; return; } int main() { test(); cout<<"going end of main"<<endl; return 0; }
实际运行输出
end of test async bbb---- going end of main
ChatGPT给出的错误预期输出
end of test going end of main async bbb----
原因分析
核心问题出在std::future的析构行为上:
std::async返回的std::future对象a是test函数的局部变量,当test函数执行到return时,局部变量会按逆序销毁:先销毁a,再销毁shared_ptr对象_。- 对于由
std::async创建的std::future,其析构函数会阻塞主线程,直到关联的异步任务完全执行完毕——不管你用的是默认启动策略还是显式指定std::launch::async。 - 所以当
test函数返回前,主线程会等待print2执行完成(输出"async"),之后才会销毁shared_ptr,执行其析构lambda输出"bbb----",最后test函数返回,主线程继续执行输出"going end of main"。
内容的提问来源于stack exchange,提问作者Michael
相关产品推荐
相关产品推荐

