最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C++11中std::packaged_task的使用詳解

 更新時(shí)間:2020年02月04日 08:51:33   作者:fengbingchun  
這篇文章主要介紹了C++11中std::packaged_task的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

C++11中的std::packaged_task是個(gè)模板類。std::packaged_task包裝任何可調(diào)用目標(biāo)(函數(shù)、lambda表達(dá)式、bind表達(dá)式、函數(shù)對(duì)象)以便它可以被異步調(diào)用。它的返回值或拋出的異常被存儲(chǔ)于能通過std::future對(duì)象訪問的共享狀態(tài)中。

std::packaged_task類似于std::function,但是會(huì)自動(dòng)將其結(jié)果傳遞給std::future對(duì)象。

std::packaged_task對(duì)象內(nèi)部包含兩個(gè)元素:(1).存儲(chǔ)的任務(wù)(stored task)是一些可調(diào)用的對(duì)象(例如函數(shù)指針、成員或函數(shù)對(duì)象的指針)( A stored task, which is some callable object (such as a function pointer, pointer to member or function object))。(2).共享狀態(tài),它可以存儲(chǔ)調(diào)用存儲(chǔ)的任務(wù)(stored task)的結(jié)果,并可以通過std::future進(jìn)行異步訪問(A shared state, which is able to store the results of calling the stored task and be accessed asynchronously through a future)。

通過調(diào)用std::packaged_task的get_future成員將共享狀態(tài)與std::future對(duì)象關(guān)聯(lián)。調(diào)用之后,兩個(gè)對(duì)象共享相同的共享狀態(tài):(1).std::packaged_task對(duì)象是異步提供程序(asynchronous provider),應(yīng)通過調(diào)用存儲(chǔ)的任務(wù)(stored task)在某個(gè)時(shí)刻將共享狀態(tài)設(shè)置為就緒。(2).std::future對(duì)象是一個(gè)異步返回對(duì)象,可以檢索共享狀態(tài)的值,并在必要時(shí)等待其準(zhǔn)備就緒。

共享狀態(tài)的生存期至少要持續(xù)到與之關(guān)聯(lián)的最后一個(gè)對(duì)象釋放或銷毀為止。

std::packaged_task不會(huì)自己啟動(dòng),你必須調(diào)用它(A packaged_task won't start on it's own, you have to invoke it)。

std::future介紹參考:http://m.fzitv.net/article/179229.htm

模板類std::packaged_task成員函數(shù)包括:

1. 構(gòu)造函數(shù):(1).默認(rèn)構(gòu)造函數(shù):無共享狀態(tài)無存儲(chǔ)任務(wù)(no shared state and no stored task)情況下初始化對(duì)象。(2). initialization constructor:該對(duì)象具有共享狀態(tài),且其存儲(chǔ)的任務(wù)由fn初始化。(3). initialization constructor with allocator。(4).禁用拷貝構(gòu)造。(5).支持移動(dòng)構(gòu)造。

2. 析構(gòu)函數(shù):(1).放棄(abandon)共享狀態(tài)并銷毀packaged_task對(duì)象。(2). 如果有其它future對(duì)象關(guān)聯(lián)到同一共享狀態(tài),則共享狀態(tài)本身不會(huì)被銷毀。(3). 如果packaged_task對(duì)象在共享狀態(tài)準(zhǔn)備就緒前被銷毀,則共享狀態(tài)自動(dòng)準(zhǔn)備就緒并包含一個(gè)std::future_error類型的異常。

3. get_future函數(shù):(1).返回一個(gè)與packaged_task對(duì)象的共享狀態(tài)關(guān)聯(lián)的std::future對(duì)象。(2).一旦存儲(chǔ)的任務(wù)被調(diào)用,返回的std::future對(duì)象就可以訪問packaged_task對(duì)象在共享狀態(tài)上設(shè)置的值或異常。(3).每個(gè)packaged_task共享狀態(tài)只能被一個(gè)std::future對(duì)象檢索(Only one future object can be retrieved for each packaged_task shared state)。(4).調(diào)用此函數(shù)后,packaged_task應(yīng)在某個(gè)時(shí)候使其共享狀態(tài)準(zhǔn)備就緒(通過調(diào)用其存儲(chǔ)的任務(wù)),否則將在銷毀后自動(dòng)準(zhǔn)備就緒并包含一個(gè)std::future_error類型的異常。

4. make_ready_at_thread_exit函數(shù):在線程退出時(shí)才使共享狀態(tài)ready而不是在調(diào)用完成后就立即ready。

5. operator=:(1).禁用拷貝賦值。(2).支持移動(dòng)賦值。

6. operator():(1).call stored task。(2).如果對(duì)存儲(chǔ)任務(wù)的調(diào)用成功完成或拋出異常,則返回的值或捕獲的異常存儲(chǔ)在共享狀態(tài),共享狀態(tài)準(zhǔn)備就緒(解除阻塞當(dāng)前等待它的所有線程)。

7. reset函數(shù):(1).在保持相同存儲(chǔ)的任務(wù)的同時(shí),以新的共享狀態(tài)重置對(duì)象。(2).允許再次調(diào)用存儲(chǔ)的任務(wù)。(3).與對(duì)象關(guān)聯(lián)的之前的共享狀態(tài)被放棄(就像packaged_task被銷毀了一樣)。(4).在內(nèi)部,該函數(shù)的行為就像是移動(dòng)賦值了一個(gè)新構(gòu)造的packaged_task一樣(Internally, the function behaves as if move-assigned a newly constructed packaged_task (with its stored task as argument))。

8. swap函數(shù)/非成員模板函數(shù)swap:交換共享狀態(tài)和存儲(chǔ)的任務(wù)(stored task)。

9. valid函數(shù):檢查packaged_task對(duì)象是否具有共享狀態(tài)。

詳細(xì)用法見下面的測(cè)試代碼,下面是從其他文章中copy的測(cè)試代碼,部分作了調(diào)整,詳細(xì)內(nèi)容介紹可以參考對(duì)應(yīng)的reference:

#include "future.hpp"
#include <iostream>
#include <future>
#include <chrono>
#include <utility>
#include <thread>
#include <functional>
#include <memory>
#include <exception> 
#include <numeric>
#include <vector>
#include <cmath>
#include <string>
 
namespace future_ {
 
///////////////////////////////////////////////////////////
// reference: http://www.cplusplus.com/reference/future/packaged_task/
int test_packaged_task_1()
{
 
{ // constructor/get_future/operator=/valid
 std::packaged_task<int(int)> foo; // default-constructed
 std::packaged_task<int(int)> bar([](int x) { return x * 2; }); // initialized
 
 foo = std::move(bar); // move-assignment
 std::cout << "valid: " << foo.valid() << "\n";
 std::future<int> ret = foo.get_future(); // get future
 std::thread(std::move(foo), 10).detach(); // spawn thread and call task
 
 int value = ret.get(); // wait for the task to finish and get result
 std::cout << "The double of 10 is " << value << ".\n";
}
 
{ // reset/operator()
 std::packaged_task<int(int)> tsk([](int x) { return x * 3; }); // package task
 
 std::future<int> fut = tsk.get_future();
 tsk(33);
 std::cout << "The triple of 33 is " << fut.get() << ".\n";
 
 // re-use same task object:
 tsk.reset();
 fut = tsk.get_future();
 std::thread(std::move(tsk), 99).detach();
 std::cout << "Thre triple of 99 is " << fut.get() << ".\n";
}
 
{ // constructor/get_future
 auto 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;
 };
 
 std::packaged_task<int(int, int)> tsk(countdown); // set up packaged_task
 std::future<int> ret = tsk.get_future(); // get future
 
 std::thread th(std::move(tsk), 5, 0); // spawn thread to count down from 5 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;
}
 
///////////////////////////////////////////////////////////
// reference: https://en.cppreference.com/w/cpp/thread/packaged_task
int test_packaged_task_2()
{
{ // lambda
 std::packaged_task<int(int, int)> task([](int a, int b) { return std::pow(a, b);});
 std::future<int> result = task.get_future();
 
 task(2, 9);
 std::cout << "task_lambda:\t" << result.get() << '\n';
}
 
{ // bind
 std::packaged_task<int()> task(std::bind([](int x, int y) { return std::pow(x, y); }, 2, 11));
 std::future<int> result = task.get_future();
 
 task();
 std::cout << "task_bind:\t" << result.get() << '\n';
}
 
{ // thread
 std::packaged_task<int(int, int)> task([](int x, int y) { return std::pow(x, y); });
 std::future<int> result = task.get_future();
 
 std::thread task_td(std::move(task), 2, 10);
 task_td.join();
 std::cout << "task_thread:\t" << result.get() << '\n';
}
 
 return 0;
}
 
///////////////////////////////////////////////////////////
// reference: https://thispointer.com/c11-multithreading-part-10-packaged_task-example-and-tutorial/
struct DBDataFetcher {
 std::string operator()(std::string token)
 {
 // Do some stuff to fetch the data
 std::string data = "Data From " + token;
 return data;
 }
};
 
int test_packaged_task_3()
{
 // Create a packaged_task<> that encapsulated a Function Object
 std::packaged_task<std::string(std::string)> task(std::move(DBDataFetcher()));
 
 // Fetch the associated future<> from packaged_task<>
 std::future<std::string> result = task.get_future();
 
 // Pass the packaged_task to thread to run asynchronously
 std::thread th(std::move(task), "Arg");
 
 // Join the thread. Its blocking and returns when thread is finished.
 th.join();
 
 // Fetch the result of packaged_task<> i.e. value returned by getDataFromDB()
 std::string data = result.get();
 std::cout << data << std::endl;
 
 return 0;
}
 
///////////////////////////////////////////////////////////
// reference: https://stackoverflow.com/questions/18143661/what-is-the-difference-between-packaged-task-and-async
int test_packaged_task_4()
{
 // sleeps for one second and returns 1
 auto sleep = []() {
 std::this_thread::sleep_for(std::chrono::seconds(1));
 return 1;
 };
 
{ // std::packaged_task
 // >>>>> A packaged_task won't start on it's own, you have to invoke it
 std::packaged_task<int()> task(sleep);
 
 auto f = task.get_future();
 task(); // invoke the function
 
 // You have to wait until task returns. Since task calls sleep
 // you will have to wait at least 1 second.
 std::cout << "You can see this after 1 second\n";
 
 // However, f.get() will be available, since task has already finished.
 std::cout << f.get() << std::endl;
}
 
{ // std::async
 // >>>>> On the other hand, std::async with launch::async will try to run the task in a different thread :
 auto f = std::async(std::launch::async, sleep);
 std::cout << "You can see this immediately!\n";
 
 // However, the value of the future will be available after sleep has finished
 // so f.get() can block up to 1 second.
 std::cout << f.get() << "This will be shown after a second!\n";
}
 
 return 0;
}
 
} // namespace future_

GitHub:https://github.com/fengbingchun/Messy_Test

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • C語言八道筆試題精講帶你掌握指針

    C語言八道筆試題精講帶你掌握指針

    C語言這門課程在計(jì)算機(jī)的基礎(chǔ)教學(xué)中一直占有比較重要的地位,然而要想突破C語言的學(xué)習(xí),對(duì)指針的掌握是非常重要的,本文將具體針對(duì)指針的基礎(chǔ)做詳盡的介紹
    2022-07-07
  • C語言實(shí)現(xiàn)音樂播放器的示例代碼

    C語言實(shí)現(xiàn)音樂播放器的示例代碼

    這篇文章主要和大家分享了一個(gè)C語言的小DEMO,可以實(shí)現(xiàn)音樂播放器功能,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,需要的可以參考一下
    2023-02-02
  • VS2019編寫C程序或者CUDA程序出現(xiàn)“無法啟動(dòng)程序,系統(tǒng)找不到指定的文件”問題的詳細(xì)解決方法

    VS2019編寫C程序或者CUDA程序出現(xiàn)“無法啟動(dòng)程序,系統(tǒng)找不到指定的文件”問題的詳細(xì)解決方法

    這篇文章主要介紹了VS2019編寫C程序或者CUDA程序出現(xiàn)“無法啟動(dòng)程序,系統(tǒng)找不到指定的文件”問題的詳細(xì)解決方法,文中通過圖文的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 利用C語言實(shí)現(xiàn)經(jīng)典游戲斗獸棋

    利用C語言實(shí)現(xiàn)經(jīng)典游戲斗獸棋

    《斗獸棋》是一款棋類游戲,整個(gè)游戲畫面是分為兩塊區(qū)域,中間有河流分割兩塊區(qū)域,有橋梁可以讓彼此的動(dòng)物過河,要取得勝利,必須占領(lǐng)那一邊動(dòng)物的巢穴獲勝利。本文將用C語言實(shí)現(xiàn)這一游戲,需要的可以參考一下
    2022-03-03
  • C++利用鏈表實(shí)現(xiàn)圖書信息管理系統(tǒng)

    C++利用鏈表實(shí)現(xiàn)圖書信息管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C++利用鏈表實(shí)現(xiàn)圖書信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • C語言使用sizeof和strlen計(jì)算數(shù)組和指針大小

    C語言使用sizeof和strlen計(jì)算數(shù)組和指針大小

    sizeof()一般是用來求取?變量?或者?類型?所占內(nèi)存空間的大小,strlen()是一個(gè)庫函數(shù)是專門用來計(jì)算?字符串?長度的,下面我們就來看看C語言如何使用sizeof和strlen計(jì)算數(shù)組和指針大小吧
    2023-11-11
  • QT圓形圖像剪切功能實(shí)現(xiàn)

    QT圓形圖像剪切功能實(shí)現(xiàn)

    這篇文章主要介紹了QT圓形圖像剪切,實(shí)現(xiàn)代碼包括剪切代碼,完整QML源碼,C++代碼,代碼簡單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • C語言中函數(shù)與指針的應(yīng)用總結(jié)

    C語言中函數(shù)與指針的應(yīng)用總結(jié)

    本篇文章是對(duì)C語言中函數(shù)與指針的應(yīng)用進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • 詳解如何用c++實(shí)現(xiàn)平衡二叉樹

    詳解如何用c++實(shí)現(xiàn)平衡二叉樹

    平衡二叉樹(Balanced Binary Tree)又被稱為AVL樹(有別于AVL算法),由前蘇聯(lián)的數(shù)學(xué)家Adelse-Velskil和Landis在1962年提出的高度平衡的二叉樹,根據(jù)科學(xué)家的英文名也稱為AVL樹。本文介紹了它的原理和如何用C++代碼來實(shí)現(xiàn)
    2021-06-06
  • C++ namespace相關(guān)語法實(shí)例分析

    C++ namespace相關(guān)語法實(shí)例分析

    這篇文章主要介紹了C++ namespace相關(guān)語法實(shí)例分析,對(duì)C++初學(xué)者有很好的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-08-08

最新評(píng)論

安溪县| 桂东县| 左云县| 邓州市| 东乡族自治县| 香港| 集安市| 阿城市| 岳阳市| 疏附县| 敦煌市| 翁源县| 永德县| 通河县| 麻江县| 万山特区| 天门市| 鹤峰县| 民乐县| 光泽县| 长春市| 黄梅县| 大理市| 安福县| 平利县| 舟山市| 塘沽区| 文成县| 山东| 云南省| 邹城市| 临泽县| 通道| 青川县| 宁德市| 额敏县| 海阳市| 油尖旺区| 武胜县| 宜兰市| 盱眙县|