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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

c++11多线程之packaged_task<>介绍与实例

發(fā)布時(shí)間:2023/12/15 c/c++ 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c++11多线程之packaged_task<>介绍与实例 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本節(jié)討論c++11中std::packaged_task的特性與使用方法

std::packaged_task<>
std::packaged_task<>是一個(gè)類模板,代表一個(gè)異步任務(wù)。封裝了
1、可調(diào)用實(shí)體,即函數(shù),lambda函數(shù)或函數(shù)對(duì)象
2、一個(gè)共享狀態(tài),通過(guò)關(guān)聯(lián)的回調(diào)來(lái)存儲(chǔ)返回的值或拋出的異常。

//從DB獲取數(shù)據(jù) std::string gtDataFromDB(std::string token){//Do some stuff to fetch the datastd::string data = "Data fetched from DB by filter :: + token;return data; }

現(xiàn)在我們想在一個(gè)單獨(dú)的線程中執(zhí)行該函數(shù),但是我們?nèi)绻谄渌€程結(jié)束的情況下在主線程中獲取結(jié)果或異常返回?
一種方法是更改函數(shù)聲明并在函數(shù)中傳遞std::promise。在傳遞線程函數(shù)中的std::promise<>對(duì)象之前,將相關(guān)的std::future<>從中取出并保存在主線程中。現(xiàn)在,在線程函數(shù)返回其值之前,應(yīng)該在傳入的std::promise參數(shù)中設(shè)置它,所以它可以在主線程的相關(guān)std::future對(duì)象中使用。參考第八節(jié)
******************************************

但是,如果我們使用std::packaged_task<>,則可以避免創(chuàng)建std::promise和更改函數(shù)代碼。


使用packaged_task<>創(chuàng)建異步任務(wù)
std::packaged_task<>可以包裝一個(gè)標(biāo)準(zhǔn)函數(shù),使其適用于作為異步功能運(yùn)行。
當(dāng)std::packaged_task<>在一個(gè)單獨(dú)的線程中運(yùn)行時(shí),它會(huì)調(diào)用相關(guān)的回調(diào)函數(shù),并將返回值或異常存儲(chǔ)在其內(nèi)部共享狀態(tài)中。該值可以通過(guò)std :: future <>對(duì)象在其他線程或主函數(shù)中訪問(wèn)。

從上面提到的函數(shù)創(chuàng)建一個(gè)packaged_task<>,運(yùn)行于獨(dú)立的線程并從其future<>對(duì)象獲取返回值。創(chuàng)建std::packaged_task<> 對(duì)象
std::packaged_task<>對(duì)象是一個(gè)類模板,因此我們需要將模板參數(shù)傳遞給packaged_task<>,即可調(diào)用函數(shù)的類型。
?

//創(chuàng)建封裝了回調(diào)函數(shù)的packaged_task<> std::packaged_task<std::string(std::string)> task(getDataFromDB);

獲取future對(duì)象

//從packaged_task<>獲取相關(guān)future<> std::future<std::string> result = task.get_future();

?傳遞packaged_task<>給線程

std::packaged_task<>可移動(dòng),但是不可復(fù)制,所以我們需要將它傳遞給線程

//傳遞packaged_task<>給線程以異步運(yùn)行 std::thread th(std::move(task), "Arg");

由于packaged_task只可以移動(dòng),不可以復(fù)制,因此我們?cè)趯⑺苿?dòng)到線程之前從它那里取出了 std::future<>對(duì)象。
線程將會(huì)執(zhí)行這個(gè)任務(wù),該任務(wù)在內(nèi)部調(diào)用相關(guān)的可調(diào)用實(shí)體,例如我們的函數(shù)getDataFromDB()。
當(dāng)這個(gè)函數(shù)給出返回值時(shí),std::packaged_task<>將其設(shè)置為關(guān)聯(lián)的共享狀態(tài),getDataFromDB()返回的結(jié)果或異常最終會(huì)在關(guān)聯(lián)的未來(lái)對(duì)象中可用。

//獲取packaged_task<>返回的結(jié)果,即getDataFromDB()返回的值。 std::string data = result.get();

get()函數(shù)將會(huì)阻塞調(diào)用線程,直到有可調(diào)用的實(shí)體返回,并且std::packaged_task<>將數(shù)據(jù)設(shè)置為其可共享的狀態(tài)。

完整的例子如下:

#include <iostream> #include <thread> #include <future> #include <string>//從DB獲取數(shù)據(jù) std::string getDataFromDB(std::string token) {//獲取數(shù)據(jù)std::string data = "Data fetched from DB by Filter :: " + token;return data; }int main() {//創(chuàng)建封裝回調(diào)函數(shù)的packaged_task<>std::packaged_task<std::string(std::string)> task(getDataFromDB);//從packaged_task<>獲取相關(guān)的future<>std::future<std::string> result = task.get_future();//將packaged_task傳遞給線程以異步運(yùn)行std::thread th(std::move(task), "Arg");//join線程,阻塞直到線程完成時(shí)返回th.join();//獲取packaged_task<>的結(jié)果,即getDataFromDB()的返回值std::string data = result.get();std::cout << data << std::endl;return 0; }

?輸出:

Data fetched from DB by Filter :: Arg

我們可以在同一行,用lambda函數(shù)或函數(shù)對(duì)象創(chuàng)建一個(gè)packaged_task

?使用lambda函數(shù)創(chuàng)建packaged_task

#include <iostream> #include <thread> #include <future> #include <string>int main() {//創(chuàng)建封裝了lambda函數(shù)的packaged_task<>std::packaged_task<std::string(std::string)> task([](std::string token) {std::string data = "Data From " + token;return data;});//從packaged_task<>獲取相關(guān)的future<>std::future<std::string> result = task.get_future();//將packaged_task傳遞給線程以異步運(yùn)行std::thread th(std::move(task), "Arg");//join線程,阻塞直到線程完成時(shí)返回th.join();//獲取packaged_task<>的結(jié)果,即getDataFromDB()的返回值std::string data = result.get();std::cout << data << std::endl;return 0; }

?輸出:

Data fetched from DB by Filter :: Arg

使用函數(shù)對(duì)象創(chuàng)建packaged_task

#include <iostream> #include <thread> #include <future> #include <string>//從DB獲取數(shù)據(jù)的函數(shù)對(duì)象 struct DBDataFetcher {std::string operator ()(std::string token) {std::string data = "Data From " + token;return data;} };int main() {//使用函數(shù)對(duì)象創(chuàng)建packaged_taskstd::packaged_task<std::string(std::string)> task(std::move(DBDataFetcher()));//從packaged_task<>獲取相關(guān)的future<>std::future<std::string> result = task.get_future();//將packaged_task傳遞給線程以異步運(yùn)行std::thread th(std::move(task), "Arg");//join線程,阻塞直到線程完成時(shí)返回th.join();//獲取packaged_task<>的結(jié)果,即getDataFromDB()的返回值std::string data = result.get();std::cout << data << std::endl;return 0; }

?輸出:

Data fetched from DB by Filter :: Arg

原文鏈接:https://blog.csdn.net/lijinqi1987/article/details/78909524

總結(jié)

以上是生活随笔為你收集整理的c++11多线程之packaged_task<>介绍与实例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。