淺談C++11 std::async()基礎(chǔ)用法示例
在 C++11 中引入的 std::async是一個用于異步執(zhí)行任務(wù)的工具,它簡化了多線程編程的復(fù)雜度,通過返回 std::future對象實現(xiàn)對異步任務(wù)結(jié)果的獲取。
??一、核心概念??
std::async用于啟動一個異步任務(wù)(可能在獨立線程中執(zhí)行),并返回一個 std::future對象,通過該對象可以:
- 阻塞等待任務(wù)完成并獲取返回值(
future::get()); - 查詢?nèi)蝿?wù)狀態(tài)(
future::valid()、future::wait_for()等); - 異常傳遞(任務(wù)中的異常會延遲到
get()時拋出)。
??二、函數(shù)原型與啟動策略??
std::async的聲明如下:
template< class Function, class... Args >
std::future<typename std::result_of<Function(Args...)>::type>
async( Function&& f, Args&&... args );
template< class Function, class... Args >
std::future<typename std::result_of<Function(Args...)>::type>
async( std::launch policy, Function&& f, Args&&... args );其中第二個模板參數(shù)是??啟動策略??(std::launch枚舉),控制任務(wù)的執(zhí)行方式:
策略 | 說明 |
|---|---|
std::launch::async | 強制在新線程中異步執(zhí)行任務(wù)(類似 std::thread直接啟動)。 |
std::launch::deferred | 延遲執(zhí)行:任務(wù)不會立即啟動,直到調(diào)用 future.get()或 wait()時才在當(dāng)前線程同步執(zhí)行。 |
默認策略(無顯式指定) | 實現(xiàn)定義(通常是 `async |
??三、基礎(chǔ)用法示例??
??1. 最簡用法(無顯式策略)??
template< class Function, class... Args >
std::future<typename std::result_of<Function(Args...)>::type>
async( Function&& f, Args&&... args );
template< class Function, class... Args >
std::future<typename std::result_of<Function(Args...)>::type>
async( std::launch policy, Function&& f, Args&&... args );std::async(compute, 2, 3)啟動異步任務(wù),傳遞函數(shù)compute和參數(shù)2, 3。future.get()阻塞主線程,直到任務(wù)完成并返回結(jié)果。
??2. 顯式指定啟動策略??
// 強制異步執(zhí)行(新線程) auto future_async = std::async(std::launch::async, compute, 2, 3); // 延遲執(zhí)行(當(dāng)前線程同步執(zhí)行) auto future_deferred = std::async(std::launch::deferred, compute, 2, 3); future_async.get(); // get()阻塞等待 future_deferred.get(); // 此時在當(dāng)前線程同步執(zhí)行 compute(2,3)
??四、參數(shù)傳遞與引用語義??
std::async支持傳遞任意可調(diào)用對象(函數(shù)、Lambda、函數(shù)對象等)和參數(shù)。若需傳遞引用,需用 std::ref包裝:
#include <functional>
void modify(int& value) {
value = 100;
}
int main() {
int x = 0;
// 錯誤:直接傳遞引用會被復(fù)制(值語義)
// auto future = std::async(modify, x);
// 正確:用 std::ref 傳遞引用
auto future = std::async(modify, std::ref(x));
future.get();
std::cout << x << std::endl; // 輸出 100(x 被修改)
return 0;
}??五、std::future 的常用接口??
std::async返回的 std::future提供以下關(guān)鍵方法:
方法 | 說明 |
|---|---|
get() | 阻塞直到任務(wù)完成,返回結(jié)果(或拋出任務(wù)中的異常);只能調(diào)用一次。 |
wait() | 阻塞直到任務(wù)完成;可多次調(diào)用。 |
wait_for(timeout) | 阻塞最多 timeout時間,返回 std::future_status(ready/timeout/deferred)。 |
wait_until(timepoint) | 阻塞直到指定時間點。 |
valid() | 檢查 future是否關(guān)聯(lián)有效結(jié)果(未調(diào)用 get()時為 true)。 |
share() | 轉(zhuǎn)換為 std::shared_future(允許多個對象共享結(jié)果)。 |
??六、異常處理??
異步任務(wù)中拋出的異常會被 std::future捕獲,直到調(diào)用 get()時重新拋出:
int risky_compute(int x) {
if (x < 0) throw std::runtime_error("x is negative");
return x * 2;
}
int main() {
auto future = std::async(risky_compute, -1);
try {
int result = future.get(); // 拋出 std::runtime_error
} catch (const std::exception& e) {
std::cerr << "Error: " << e.what() << ""; // 捕獲異常
}
return 0;
}??七、注意事項??
??生命周期管理??:
std::future析構(gòu)時,若任務(wù)未完成且未被get()或wait(),可能導(dǎo)致程序終止(取決于實現(xiàn))。若需共享結(jié)果,使用std::shared_future。??線程復(fù)用??:
std::async不保證任務(wù)一定在新線程中執(zhí)行(尤其是deferred策略或編譯器優(yōu)化),依賴具體實現(xiàn)。??性能開銷??:
相比手動管理
std::thread,std::async自動管理線程生命周期,但頻繁創(chuàng)建小任務(wù)可能有額外開銷(適合中高耗時任務(wù))。
??八、典型應(yīng)用場景??
- ??并行計算??:同時執(zhí)行多個獨立任務(wù)(如圖像處理中的多區(qū)域計算)。
- ??異步IO??:發(fā)起IO操作后異步等待結(jié)果,避免阻塞主線程。
- ??任務(wù)編排??:結(jié)合
std::future::wait_for實現(xiàn)超時控制(如監(jiān)控任務(wù)是否超時)。
??總結(jié)??
std::async是 C++11 中簡化異步編程的核心工具,通過 std::future提供結(jié)果獲取和狀態(tài)查詢能力。合理使用其啟動策略和異常處理機制,可有效提升代碼的并發(fā)性能和可維護性。
到此這篇關(guān)于淺談C++11 std::async()基礎(chǔ)用法示例的文章就介紹到這了,更多相關(guān)C++11 std::async()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語言數(shù)據(jù)結(jié)構(gòu)之迷宮求解問題
這篇文章主要為大家詳細介紹了C語言數(shù)據(jù)結(jié)構(gòu)之迷宮求解問題,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-03-03
C語言的isatty函數(shù)和ttyname函數(shù)以及sendmsg函數(shù)用法
這篇文章主要介紹了C語言的isatty函數(shù)和ttyname函數(shù)以及sendmsg函數(shù)用法,是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09
C語言 深入解讀數(shù)據(jù)結(jié)構(gòu)之堆的實現(xiàn)
堆就是用數(shù)組實現(xiàn)的二叉樹,所以它沒有使用父指針或者子指針。堆根據(jù)“堆屬性”來排序,“堆屬性”決定了樹中節(jié)點的位置2021-11-11
C++實現(xiàn)結(jié)束應(yīng)用進程小工具
這篇文章主要為大家詳細介紹了C++實現(xiàn)結(jié)束應(yīng)用進程小工具,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-05-05
C++算法之在無序數(shù)組中選擇第k小個數(shù)的實現(xiàn)方法
這篇文章主要介紹了C++算法之在無序數(shù)組中選擇第k小個數(shù)的實現(xiàn)方法,涉及C++數(shù)組的遍歷、判斷、運算等相關(guān)操作技巧,需要的朋友可以參考下2017-03-03

