std::future ---C++17 多线程
std::future —C++17 多線程
std::future
C++標(biāo)準(zhǔn)程序庫(kù)使用future來(lái)模擬這類(lèi)一次性事件:若線程需等待某個(gè)特定的一次性事件發(fā)生,則會(huì)以恰當(dāng)?shù)姆绞饺〉靡粋€(gè)future,它代表目標(biāo)事件;接著,該線程就能一邊執(zhí)行其他任務(wù)(光顧機(jī)場(chǎng)茶座),一邊在future上等待;同時(shí),它以短暫的間隔反復(fù)查驗(yàn)?zāi)繕?biāo)事件是否已經(jīng)發(fā)生(查看出發(fā)時(shí)刻表)。這個(gè)線程也可以轉(zhuǎn)換運(yùn)行模式,先不等目標(biāo)事件發(fā)生,直接暫緩當(dāng)前任務(wù),而切換到別的任務(wù),及至必要時(shí),才回頭等待future準(zhǔn)備就緒。future可能與數(shù)據(jù)關(guān)聯(lián)(如航班的登機(jī)口),也可能未關(guān)聯(lián)。一旦目標(biāo)事件發(fā)生,其future即進(jìn)入就緒狀態(tài),無(wú)法重置。
總之,先保存一個(gè)事件(創(chuàng)建future對(duì)象),在未來(lái)獲取事件的結(jié)果(get)
#pragma once #include <future> #include <iostream> #include <format> using namespace std;std::string get_answer_from_hard_question() {std::this_thread::sleep_for(2s);cout << "id: " << std::this_thread::get_id << endl;return string("答案在這\n"); } void do_something() {std::this_thread::sleep_for(5s);cout << "id: " << std::this_thread::get_id << endl;cout << "結(jié)束任務(wù)\n"; }void start() {std::future<std::string> the_ans = std::async(std::launch::async,get_answer_from_hard_question);do_something();std::cout << std::format("答案是:{}", the_ans.get()); }創(chuàng)建future對(duì)象的方法
#include <string> #include <future> struct X {void foo(int,std::string const&);std::string bar(std::string const&); }; X x; auto f1=std::async(&X::foo,&x,42,"hello"); ?--- ①調(diào)用p->foo(42,"hello"),其中p的值是&x,即x的地址 auto f2=std::async(&X::bar,x,"goodbye"); ?--- ②調(diào)用tmpx.bar("goodbye"),其中tmpx是x的副本 struct Y {double operator()(double); }; Y y; auto f3=std::async(Y(),3.141); ?--- ③調(diào)用tmpy(3.141)。其中,由Y()生成一個(gè)匿名變量,傳遞給std::async(),進(jìn)而發(fā)生移動(dòng)構(gòu)造。在std::async()內(nèi)部產(chǎn)生對(duì)象tmpy,在tmpy上執(zhí)行Y::operator()(3.141) auto f4=std::async(std::ref(y),2.718); ?--- ④調(diào)用y(2.718) X baz(X&); std::async(baz,std::ref(x)); ?--- ⑤調(diào)用baz(x) class move_only { public:move_only();move_only(move_only&&)move_only(move_only const&) = delete;move_only& operator=(move_only&&);move_only& operator=(move_only const&) = delete;void operator()(); }; auto f5=std::async(move_only()); ?--- ⑥調(diào)用tmp(),其中tmp等價(jià)于std::move (move_only()),它的產(chǎn)生過(guò)程與③相似按默認(rèn)情況下,std::async()的具體實(shí)現(xiàn)會(huì)自行決定——等待future時(shí),是啟動(dòng)新線程,還是同步執(zhí)行任務(wù)。大多數(shù)情況下,我們正希望如此。不過(guò),我們還能夠給std::async()補(bǔ)充一個(gè)參數(shù),以指定采用哪種運(yùn)行方式。參數(shù)的類(lèi)型是std::launch,其值可以是std::launch::deferred或std::launch::async。前者指定在當(dāng)前線程上延后調(diào)用任務(wù)函數(shù),等到在future上調(diào)用了wait()或get(),任務(wù)函數(shù)才會(huì)執(zhí)行;后者指定必須另外開(kāi)啟專(zhuān)屬的線程,在其上運(yùn)行任務(wù)函數(shù)。該參數(shù)的值還可以是std::launch::deferred | std::launch:: async,表示由std::async()的實(shí)現(xiàn)自行選擇運(yùn)行方式。最后這項(xiàng)是參數(shù)的默認(rèn)值。若延后調(diào)用任務(wù)函數(shù),則任務(wù)函數(shù)有可能永遠(yuǎn)不會(huì)運(yùn)行。舉例如下。
auto f6=std::async(std::launch::async,Y(),1.2); ?--- ①運(yùn)行新線程auto f7=std::async(std::launch::deferred,baz,std::ref(x)); ?--- ②在wait()或get()內(nèi)部運(yùn)行任務(wù)函數(shù) auto f8=std::async( ?--- std::launch::deferred | std::launch::async,baz,std::ref(x)); auto f9=std::async(baz,std::ref(x)); ?--- ③交由實(shí)現(xiàn)自行選擇運(yùn)行方式 f7.wait(); ?--- ④前面②處的任務(wù)函數(shù)調(diào)用被延后,到這里才運(yùn)行總結(jié)
以上是生活随笔為你收集整理的std::future ---C++17 多线程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Syncd - 开源自动化部署工具
- 下一篇: 获取摄像机,摄像机切换Learn Unr