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

