C++11異步編程 — async和future
C++11引入了async
和future
機制,用于簡化異步編程和并發操作。這兩個組件位于<future>
頭文件中,提供了高級的異步任務管理接口。
一、async
1.定義
std::async
std::async
是一個函數模板,用于啟動一個異步任務。它返回一個std::future
對象,該對象可以用來獲取異步任務的結果。std::async
的執行方式可以通過std::launch
策略來控制。如下:
future<int> myf = async(launch::async,Func,20,30);
2.主要功能
①啟動一個異步任務,返回一個future對象。
②啟動策略:
EXPORT_STD enum class launch { // names for launch options passed to asyncasync = 0x1,deferred = 0x2
};
launch::async :強制在新線程中啟動異步任務。
launch::deferred:延遲執行,只有當future的get()或者wait函數被調用時,任務才會在調用線程中執行。
默認策略(不指定) - 由實現決定,可能是異步或延遲
二、future
1.定義:
future是一個類模板,用于存儲異步執行結果,它提供了一種機制,允許用戶在某個異步操作完成時獲取其結果。std::future
對象可以與線程、異步任務或其他并發操作相關聯。
2.主要功能
①通過std::future
的get()
方法,可以獲取異步操作的結果。如果異步操作尚未完成,get()
會阻塞當前線程,直到結果可用。
②它提供了以下主要方法:
get()
- 獲取結果(如果結果未準備好會阻塞)wait()
- 等待結果可用(阻塞但不獲取結果)wait_for()
/wait_until()
- 帶超時的等待valid()
- 檢查future是否關聯了共享狀態
三、 std::async
和std::future
的使用場景
1.異步任務處理:適用于需要在后臺執行耗時操作,而主線程可以繼續執行其他任務的場景。
2.多線程數據共享:通過std::future
獲取異步任務的結果,避免了直接使用線程時可能出現的線程同步問題。
3.簡化并發編程:提供了一種簡潔的方式來實現異步任務的啟動和結果獲取,降低了并發編程的復雜性。
四、注意事項:
1.如果不保留async
返回的future對象,其析構函數會阻塞等待任務完成(類似于隱式join)。
2.線程安全:std::future
和std::async
是線程安全的,但用戶需要確保在使用std::future
的get()
方法時,不會出現對同一std::future
對象的多次調用,future::get()
只能調用一次,調用后future變為無效。
3.資源管理:std::future
對象在析構時會自動銷毀關聯的異步任務,但如果任務尚未完成,可能會導致資源泄漏或未定義行為。
4.性能考慮:雖然std::async
可以自動選擇執行策略,但在某些情況下,顯式指定std::launch::async
或std::launch::deferred
可以更好地控制任務的執行方式,從而優化性能。
示例代碼:
#include <iostream>
#include<thread>
#include<future>
using namespace std;int Func(int a,int b)
{cout << "Sub thread ID:" << this_thread::get_id() << endl;cout << "this is MyFunc" << endl;return a + b;
}int main()
{future<int> myf = async(launch::async,Func,20,30);cout <<"Main Thread Id:"<< this_thread::get_id() << endl;myf.wait();cout<<"myf == " << myf.get()<< endl; std::cout << "Hello World!\n";
}
代碼運行結果:
好了,關于async和future的介紹就到這里了。