日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++——异步操作(std::future、std::async、std::packaged_task、std::promise)

發布時間:2024/4/17 c/c++ 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++——异步操作(std::future、std::async、std::packaged_task、std::promise) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 一、std::future與std::async
    • 1.基本概念
    • 2.代碼演示
  • 二、std::future與std::packaged_task
    • 1.基本知識
    • 2.代碼演示
  • 三、std::future與std::promise
    • 1.基本知識
    • 2.代碼演示


一、std::future與std::async

1.基本概念

(1)std::future的基本知識
std::future期待一個返回,從一個異步調用的角度來說,future更像是執行函數的返回值,C++標準庫使用std::future為一次性事件建模,如果一個事件需要等待特定的一次性事件,那么這線程可以獲取一個future對象來代表這個事件。
異步調用往往不知道何時返回,但是如果異步調用的過程需要同步,或者說后一個異步調用需要使用前一個異步調用的結果。這個時候就要用到future。
線程可以周期性的在這個future上等待一小段時間,檢查future是否已經ready,如果沒有,該線程可以先去做另一個任務,一旦future就緒,該future就無法復位(無法再次使用這個future等待這個事件),所以future代表的是一次性事件

(2)std::future的類型
在庫的頭文件中聲明了兩種future,唯一future(std::future)和共享future(std::shared_future)這兩個是參照std::unique_ptr和std::shared_ptr設立的,前者的實例是僅有的一個指向其關聯事件的實例,而后者可以有多個實例指向同一個關聯事件,當事件就緒時,所有指向同一事件的std::shared_future實例會變成就緒。
std::future是一個模板,例如std::future,模板參數就是期待返回的類型,雖然future被用于線程間通信,但其本身卻并不提供同步訪問,熱門必須通過互斥元或其他同步機制來保護訪問。

(1)std::future的使用時機
future使用的時機是當你不需要立刻得到一個結果的時候,你可以開啟一個線程幫你去做一項任務,并期待這個任務的返回,但是std::thread并沒有提供這樣的機制,這就需要用到std::async和std::future(都在頭文件#include < future >中聲明)std::async返回一個std::future對象,而不是給你一個確定的值(所以當你不需要立刻使用此值的時候才需要用到這個機制)。當你需要使用這個值的時候,對future使用get(),線程就會阻塞直到future就緒,然后返回該值。

2.代碼演示

代碼1:未使用std::future

#include<iostream> #include<future>int add(int a, int b) {std::this_thread::sleep_for(std::chrono::seconds(5));//休眠五秒return a + b; }void fun() {std::cout << "this is fun()" << std::endl; }int main() {int c = add(1,2);//這行代碼執行需要5秒,5秒后再向下執行fun();std::cout << c << std::endl;return 0; }


代碼2:使用future

#include<iostream> #include<future>int add(int a, int b) {std::this_thread::sleep_for(std::chrono::seconds(5));//休眠五秒return a + b; }void fun() {std::cout << "this is fun()" << std::endl; }int main() {std::future<decltype(add(1, 2))> result = std::async(add, 1, 2);//auto result = std::async(add, 1, 2); //OK 可以使用占位符auto進行類型推導//std::future<int> result = std::async(add, 1, 2);//OK 由于知道函數的返回類型 所以可以直接確定模板類型int//std::future<decltype(add, int, int)>result = std::async(add, 1, 2);//errorfun();std::this_thread::sleep_for(std::chrono::seconds(5));//休眠5秒std::cout << result.get() << std::endl;return 0; }


跟thread類似,async允許你通過將額外的參數添加到調用中,來將附加參數傳遞給函數。如果傳入的函數指針是某個類的成員函數,則還需要將類對象指針傳入(直接傳入,傳入指針,或者是std::ref封裝)。
默認情況下,std::async是否啟動一個新線程,或者在等待future時,任務是否同步運行都取決于你給的參數。這個參數為std::launch類型std::launch::defered表明該函數會被延遲調用,直到在future上調用get()或者wait()為止std::launch::async,表明函數會在自己創建的線程上運行

二、std::future與std::packaged_task

1.基本知識

如果說std::async和std::future還是分開看的關系的話,那么std::packaged_task就是將任務和future綁定在一起的模板,是一種封裝對任務的封裝。
可以通過std::packaged_task對象獲取任務相關聯的future,調用get_future()方法可以獲得std::packaged_task對象綁定的函數的返回值類型的future。std::packaged_task的模板參數是函數簽名
例如int add(int a, intb)的函數簽名就是int(int, int)

2.代碼演示

由于和第一大點的差不多,這里簡單代碼演示

#include<iostream> #include<future>int add(int a, int b) {std::this_thread::sleep_for(std::chrono::seconds(5));//休眠五秒return a + b; }void fun() {std::cout << "this is fun()" << std::endl; }int main() {std::packaged_task<int(int, int)>task(add);//將函數和task綁定在一起了std::future<int> result = task.get_future();fun();task(1, 2);//相當于執行函數 必須執行 否則的話 result.get()會一直阻塞 當我們執行這個task(1,2)的時候才算開始執行add函數 換句話說,當我們執行task(1,2)的時候,才會執行add函數里的5秒休眠std::cout << result.get() << std::endl;return 0; }

三、std::future與std::promise

1.基本知識

從字面意思上理解promise代表一個承諾。promise比std::packaged_task抽象層次低。
std::promise提供了一種設置值的方式,它可以在這之后通過相關聯的std::future對象進行讀取。換種說法,之前已經說過std::future可以讀取一個異步函數的返回值了,那么這個std::promise就提供一種方式手動讓future就緒。

2.代碼演示

#include <future> #include <string> #include <thread> #include <iostream> using namespace std; void print(std::promise<std::string>& p) {this_thread::sleep_for(chrono::seconds(5));p.set_value("There is the result whitch you want."); } void do_some_other_things() {std::cout << "Hello World" << std::endl; } int main() {std::promise<std::string> promise;std::future<std::string> result = promise.get_future();//thread的時候傳入引用必須使用std::ref()函數std::thread t(print, std::ref(promise));//開始執行print函數 do_some_other_things();//打印“hellowworld”this_thread::sleep_for(chrono::seconds(5));std::cout << result.get() << std::endl;//什么時候想要線程的返回值什么時候result.get()t.join();return 0; }

總結

以上是生活随笔為你收集整理的C++——异步操作(std::future、std::async、std::packaged_task、std::promise)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。