(1) std::async 會返回一個 std::future 對象, 這個對象持有最終計算出來的結果. 當須要這個值時, 只須要調用對象的get()成員函數. 而且直到「指望」狀態爲就緒的狀況下, 線程纔會阻塞; 以後,返回計算結果. 編程
std::future<int> answer = std::async([] { std::stringstream stm; stm << "future id:" << std::this_thread::get_id() << std::endl; std::cout << stm.str(); int sum = 0; for (int i = 1; i <= 100; i++) { sum += i; std::cout << i << " "; } std::cout << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); // 增長延遲(1s) return sum; }); std::stringstream stm; stm << "main id:" << std::this_thread::get_id() << std::endl; std::cout << stm.str(); std::cout << "answer is: " << answer.get() << std::endl; // 此時會被阻塞, 直到異步任務返回 std::cout << "tag 2" << std::endl;
(2) std::async 容許經過添加額外的調用參數, 向函數傳遞額外的參數.
若是第一個參數是一個指向成員函數的指針, 第二個參數提供有這個函數成員類的具體對象(能夠經過指針, 或者包裝在 std::ref 中), 剩餘的參數可做爲成員函數的參數傳入.
不然, 隨後的全部參數將做爲函數的參數, 或做爲指定可調用對象的第一個參數. 好比 std::thread, 當參數爲右值(rvalues)時, 拷貝操做將使用移動的方式轉移原始數據. 這就容許使用「只移動」類型做爲函數對象和參數.併發
class XFun { public: XFun() {} ~XFun() {} void f(const std::string& str) { std::stringstream stm; stm << "f called. " << this << "-->" << str << std::endl; std::cout << stm.str(); } std::string g(const std::string& str) { std::stringstream stm; stm << str << "[--> add by function g] " << this; return stm.str(); } //XFun& operator=(const XFun&) = delete; //XFun(const XFun&) = delete; void operator()(const std::string& str) { std::stringstream stm; stm << "operator() called. " << this << "-->" << str << std::endl; std::cout << stm.str(); } }; XFun x; std::cout << "addr of x:" << &x << std::endl; std::async(&XFun::f, &x, std::string("test f()")); std::future<std::string> f2 = std::async(&XFun::g, x, std::string("test g() temp")); // 建立一個 x 對象的副本傳入, 刪除賦值函數後, 將不能編譯 std::async(std::ref(x), std::string("test operator()")); std::async(XFun(), std::string("test operator() temp")); // 建立一個 XFun 的臨時對象傳入 std::cout << f2.get() << std::endl;
(3) 默認狀況下, std::async 會啓動一個新線程來完成任務, 可是也能夠指定額外的執行方式:
std::launch::defered 指定等到 wait 或 get 被調用時才執行.
std::launch::async 指定必須到獨立的線程中執行.
默認爲: std::launch::defered | std::launch::async異步
auto f3 = std::async(std::launch::deferred, [] { std::stringstream stm; stm << "f3 called. TID:" << std::this_thread::get_id() << std::endl; std::cout << stm.str(); }); auto f4 = std::async(std::launch::async, [] { std::stringstream stm; stm << "f4 called. TID:" << std::this_thread::get_id() << std::endl; std::cout << stm.str(); }); std::stringstream stm; stm << "main. TID:" << std::this_thread::get_id() << std::endl; std::cout << stm.str(); std::this_thread::sleep_for(std::chrono::seconds(1)); f3.wait();