如何确保std::async任务的启动时机?相关技术疑问解析
关于std::async(std::launch::async)的行为解析
原cppreference示例的行为确认
cppreference里的示例中,f()和g()确实会在同一线程执行且g()在f()之后运行。原因是直接调用std::async(std::launch::async, f)时,返回的std::future会在析构时阻塞,直到异步任务完成。比如代码:
std::async(std::launch::async, f); // 临时future对象,析构时等待f完成 std::async(std::launch::async, g); // 等f完成后才会启动g的异步任务
这里临时的std::future对象在语句结束时就会被销毁,销毁过程中会等待绑定的异步任务执行完毕,所以g()必须等f()做完才能开始。
你提供的代码的行为分析
你写的代码里:
void ff(){std::async(std::launch::async, []{ f(); });} void gg(){std::async(std::launch::async, []{ g(); });} int main(){ ff(); gg(); }
情况和原示例完全一致——ff()里的std::async返回的临时future会在ff()函数结束时析构,阻塞直到f()完成;之后才会进入gg(),启动g()的任务。所以g()还是要等f()做完才能启动,并没有实现并行。
如何正确理解std::async的Notes部分
核心要点:
std::launch::async只是要求任务必须在单独的线程执行,但不保证线程会立即启动——不过日常开发中最容易踩的坑是临时future的隐式阻塞。- 要避免这种阻塞,必须保存
std::async返回的std::future对象,不让它立即析构:int main(){ auto fut_f = std::async(std::launch::async, f); auto fut_g = std::async(std::launch::async, g); // 这里f和g会并行执行,直到调用fut_f.get()/fut_g.get()或者fut_f/fut_g析构时才会等待 } - 另外,标准允许实现对异步线程数量做限制,比如系统资源不足时,
std::launch::async可能延迟启动新线程,但这种场景相对少见。
补充示例
错误用法(串行执行)
#include <iostream> #include <thread> #include <future> #include <chrono> void f() { std::cout << "f start\n"; std::this_thread::sleep_for(std::chrono::seconds(2)); std::cout << "f end\n"; } void g() { std::cout << "g start\n"; std::this_thread::sleep_for(std::chrono::seconds(2)); std::cout << "g end\n"; } int main() { auto start = std::chrono::steady_clock::now(); std::async(std::launch::async, f); std::async(std::launch::async, g); auto end = std::chrono::steady_clock::now(); std::cout << "Total time: " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count() << "s\n"; }
输出(总耗时约4秒,串行执行):
f start
f end
g start
g end
Total time: 4s
正确用法(并行执行)
#include <iostream> #include <thread> #include <future> #include <chrono> void f() { std::cout << "f start\n"; std::this_thread::sleep_for(std::chrono::seconds(2)); std::cout << "f end\n"; } void g() { std::cout << "g start\n"; std::this_thread::sleep_for(std::chrono::seconds(2)); std::cout << "g end\n"; } int main() { auto start = std::chrono::steady_clock::now(); auto fut_f = std::async(std::launch::async, f); auto fut_g = std::async(std::launch::async, g); fut_f.get(); fut_g.get(); auto end = std::chrono::steady_clock::now(); std::cout << "Total time: " << std::chrono::duration_cast<std::chrono::seconds>(end - start).count() << "s\n"; }
输出(总耗时约2秒,并行执行):
f start
g start
f end
g end
Total time: 2s
内容的提问来源于stack exchange,提问作者f1msch
相关产品推荐
相关产品推荐

