轉 C++11 使用非同步程式設計std::async和std::future

原文 https://www。cnblogs。com/moodlxs/p/10111601。html

先說明一點:std::asyanc是std::future的高階封裝, 一般我們不會直接使用std::futrue,而是使用對std::future的高階封裝std::async。 下面分別說一下。

一、std::async基本用法

std::future可以從非同步任務中獲取結果,一般與std::async配合使用,std::async用於建立非同步任務,實際上就是建立一個執行緒執行相應任務。

std::async就是非同步程式設計的高階封裝,封裝了std::future的操作,基本上可以代替std::thread 的所有事情。

std::async的操作,其實相當於封裝了std::promise、std::packaged_task加上std::thread。

使用程式碼如下:

轉 C++11 使用非同步程式設計std::async和std::future

#include #include #include bool is_prime(int x){ for (int i=0; i fut = std::async(is_prime, 700020007); std::cout << “please wait”; std::chrono::milliseconds span(100); while (fut。wait_for(span) != std::future_status::ready) std::cout << “。”; std::cout << std::endl; bool ret = fut。get(); std::cout << “final result: ” << stringify(ret) << std::endl; return 0;}

轉 C++11 使用非同步程式設計std::async和std::future

std::async會首先建立執行緒執行is_prime(700020007), 任務建立之後,std::async立即返回一個std::future物件。

主執行緒既可使用std::future::get獲取結果,如果呼叫過程中,任務尚未完成,則主執行緒阻塞至任務完成。

主執行緒也可使用std::future::wait_for等待結果返回,wait_for可設定超時時間,如果在超時時間之內任務完成,則返回std::future_status::ready狀態;如果在超時時間之內任務尚未完成,則返回std::future_status::timeout狀態。

上面先說了通用的做法,然後我們瞭解一下std::future、std::promise、std::packaged_task

二、std::future說明

future物件是std::async、std::promise、std::packaged_task的底層物件,用來傳遞其他執行緒中操作的資料結果。

三、std::promise用法

std::promise的作用就是提供一個不同執行緒之間的資料同步機制,它可以儲存一個某種型別的值,並將其傳遞給對應的future, 即使這個future不在同一個執行緒中也可以安全的訪問到這個值。

示例程式碼:

// promise example#include // std::cout#include // std::ref#include // std::thread#include // std::promise, std::futurevoid print_int (std::future& fut) { int x = fut。get(); std::cout << “value: ” << x << ‘\n’;}int main (){ std::promise prom; // create promise std::future fut = prom。get_future(); // engagement with future std::thread th1 (print_int, std::ref(fut)); // send future to new thread prom。set_value (10); // fulfill promise // (synchronizes with getting the future) th1。join(); return 0;}

Output:

value: 10

四、std::packaged_task用法

std::packaged_task的作用就是提供一個不同執行緒之間的資料同步機制,它可以儲存一個函式操作,並將其返回值傳遞給對應的future, 而這個future在另外一個執行緒中也可以安全的訪問到這個值。

示例程式碼:

// packaged_task example#include // std::cout#include // std::packaged_task, std::future#include // std::chrono::seconds#include // std::thread, std::this_thread::sleep_for// count down taking a second for each value:int countdown (int from, int to) { for (int i=from; i!=to; ——i) { std::cout << i << ‘\n’; std::this_thread::sleep_for(std::chrono::seconds(1)); } std::cout << “Lift off!\n”; return from-to;}int main (){ std::packaged_task tsk (countdown); // set up packaged_task std::future ret = tsk。get_future(); // get future std::thread th (std::move(tsk),10,0); // spawn thread to count down from 10 to 0 // 。。。 int value = ret。get(); // wait for the task to finish and get result std::cout << “The countdown lasted for ” << value << “ seconds。\n”; th。join(); return 0;}