用C 11的std async代替執行緒的建立

2021-08-21 18:02:39 字數 3414 閱讀 9581

c++11中增加了執行緒,使得我們可以非常方便的建立執行緒,它的基本用法是這樣的:

void f(int n);

std::thread t(f, n + 1);

t.join();

std::future是乙個非常有用也很有意思的東西,簡單說std::future提供了一種訪問非同步操作結果的機制。從字面意思來理解,它表示未來,我覺得這個名字非常貼切,因為乙個非同步操作我們是不可能馬上就獲取操作結果的,只能在未來某個時候獲取,但是我們可以以同步等待的方式來獲取結果,可以通過查詢future的狀態(future_status)來獲取非同步操作的結果。future_status有三種狀態:

//查詢future的狀態

std::future_status status;

do else if (status == std::future_status::timeout) else if (status == std::future_status::ready)

} while (status != std::future_status::ready);

獲取future結果有三種方式:get、wait、wait_for,其中get等待非同步操作結束並返回結果,wait只是等待非同步操作完成,沒有返回值,wait_for是超時等待返回結果。

std::promisepr;

std::thread t((std::promise& p),std::ref(pr));

std::futuref = pr.get_future();

auto r = f.get();

std::packaged_task它包裝了乙個可呼叫的目標(如function, lambda expression, bind expression, or another function object),以便非同步呼叫,它和promise在某種程度上有點像,promise儲存了乙個共享狀態的值,而packaged_task儲存的是乙個函式。它的基本用法:

std::packaged_tasktask(());

std::thread t1(std::ref(task));

std::futuref1 = task.get_future();

auto r1 = f1.get();

至此, 我們介紹了std::async相關的幾個物件std::future、std::promise和std::packaged_task,其中std::promise和std::packaged_task的結果最終都是通過其內部的future返回出來的,不知道讀者有沒有搞糊塗,為什麼有這麼多東西出來,他們之間的關係到底是怎樣的?且聽我慢慢道來,std::future提供了乙個訪問非同步操作結果的機制,它和執行緒是乙個級別的屬於低層次的物件,在它之上高一層的是std::packaged_task和std::promise,他們內部都有future以便訪問非同步操作結果,std::packaged_task包裝的是乙個非同步操作,而std::promise包裝的是乙個值,都是為了方便非同步操作的,因為有時我需要獲取執行緒中的某個值,這時就用std::promise,而有時我需要獲乙個非同步呼叫操作的返回值,這時就用std::packaged_task。那std::promise和std::packaged_task之間又是什麼關係呢?說他們沒關係也關係,說他們有關係也有關係,都取決於你了,因為我可以將乙個非同步操作的結果儲存到std::promise中。如果讀者還沒搞清楚他們的關係的話,我就用更通俗的話來解釋一下。比如,乙個小夥子給乙個姑娘表白真心的時候也許會說:」我許諾會給你乙個美好的未來「或者」我會努力奮鬥為你創造乙個美好的未來「。姑娘往往會說:」我等著「。現在我來將這三句話用c++11來翻譯一下:

小夥子說:我許諾會給你乙個美好的未來等於c++11中"std::promise a std::future";

小夥子說:我會努力奮鬥為你創造乙個美好的未來等於c++11中"std::packaged_task a future";

姑娘說:我等著等於c++11中"future.get()/wait()";

小夥子兩句話的個中差異,自己琢磨一下,這點差異也是std::promise和std::packaged_task的差異。現實中的山盟海誓靠不靠得住我不知道,但是c++11中的許諾和未來是一定可靠的,發起來了許諾就一定有未來。細想起來c++11標準的制定者選定的關鍵字真是貼切而有意思!好了,插科打諢到此了,現在言歸正傳,回過頭來說說std::async。

std::async又是幹啥的,已經有了td::future、std::promise和std::packaged_task,夠多的了,真的還要乙個std::async來湊熱鬧嗎,std::async表示很委屈:我不是來湊熱鬧的,我是來幫忙的。是的,std::async是為了讓使用者的少費點腦子的,它讓這三個物件默契的工作。大概的工作過程是這樣的:std::async先將非同步操作用std::packaged_task包裝起來,然後將非同步操作的結果放到std::promise中,這個過程就是創造未來的過程。外面再通過future.get/wait來獲取這個未來的結果,怎麼樣,std::async真的是來幫忙的吧,你不用再想到底該怎麼用std::future、std::promise和std::packaged_task了,std::async已經幫你搞定一切了!

現在來看看std::async的原型async(std::launch::async | std::launch::deferred, f, args...),第乙個引數是執行緒的建立策略,有兩種策略,預設的策略是立即建立執行緒:

第二個引數是執行緒函式,第三個引數是執行緒函式的引數。

std::async基本用法:

std::futuref1 = std::async(std::launch::async, ()); 

cout

std::cout << "waiting...\n";

std::future_status status;

do else if (status == std::future_status::timeout) else if (status == std::future_status::ready)

} while (status != std::future_status::ready);

std::cout << "result is " << future.get() << '\n';

可能的結果:

waiting...

timeout

timeout

ready!

result is 8

std::async是更高層次上的非同步操作,使我們不用關注執行緒建立內部細節,就能方便的獲取非同步執行狀態和結果,還可以指定執行緒建立策略,應該用std::async替代執行緒的建立,讓它成為我們做非同步操作的首選。

用C 11的std async代替執行緒的建立

c 11中增加了執行緒,使得我們可以非常方便的建立執行緒,它的基本用法是這樣的 void f int n std thread t f,n 1 t.join std future是乙個非常有用也很有意思的東西,簡單說std future提供了一種訪問非同步操作結果的機制。從字面意思來理解,它表示未來...

C 11多執行緒 std async

std async可以認為是封裝了乙個std promise,該函式返回乙個std future,用於獲取其他執行緒的資料。該函式的本質是內部封裝構造了乙個執行緒,然後傳遞給乙個std promise,之後返回乙個對應的std future。如果不是執行緒池,而僅僅是非同步呼叫,那麼非常推薦使用該模...

(原創)用c 11實現簡潔的ScopeGuard

scopeguard的作用是確保資源面對異常時總能被成功釋放,就算沒有正常返回。慣用法讓我們在建構函式裡獲取資源,當因為異常或者正常作用域結束,那麼在析構函式裡釋放資源。總是能釋放資源。如果沒有異常丟擲則正常結束,只是有異常發生或者沒有正常退出時釋放資源。關於scopegaurd的概念想多了解一點的...