std::future ---C++17 多线程
std::future —C++17 多線程
std::future
C++標準程序庫使用future來模擬這類一次性事件:若線程需等待某個特定的一次性事件發(fā)生,則會以恰當?shù)姆绞饺〉靡粋€future,它代表目標事件;接著,該線程就能一邊執(zhí)行其他任務(wù)(光顧機場茶座),一邊在future上等待;同時,它以短暫的間隔反復查驗?zāi)繕耸录欠褚呀?jīng)發(fā)生(查看出發(fā)時刻表)。這個線程也可以轉(zhuǎn)換運行模式,先不等目標事件發(fā)生,直接暫緩當前任務(wù),而切換到別的任務(wù),及至必要時,才回頭等待future準備就緒。future可能與數(shù)據(jù)關(guān)聯(lián)(如航班的登機口),也可能未關(guān)聯(lián)。一旦目標事件發(fā)生,其future即進入就緒狀態(tài),無法重置。
總之,先保存一個事件(創(chuàng)建future對象),在未來獲取事件的結(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對象的方法
#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()生成一個匿名變量,傳遞給std::async(),進而發(fā)生移動構(gòu)造。在std::async()內(nèi)部產(chǎn)生對象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等價于std::move (move_only()),它的產(chǎn)生過程與③相似按默認情況下,std::async()的具體實現(xiàn)會自行決定——等待future時,是啟動新線程,還是同步執(zhí)行任務(wù)。大多數(shù)情況下,我們正希望如此。不過,我們還能夠給std::async()補充一個參數(shù),以指定采用哪種運行方式。參數(shù)的類型是std::launch,其值可以是std::launch::deferred或std::launch::async。前者指定在當前線程上延后調(diào)用任務(wù)函數(shù),等到在future上調(diào)用了wait()或get(),任務(wù)函數(shù)才會執(zhí)行;后者指定必須另外開啟專屬的線程,在其上運行任務(wù)函數(shù)。該參數(shù)的值還可以是std::launch::deferred | std::launch:: async,表示由std::async()的實現(xiàn)自行選擇運行方式。最后這項是參數(shù)的默認值。若延后調(diào)用任務(wù)函數(shù),則任務(wù)函數(shù)有可能永遠不會運行。舉例如下。
auto f6=std::async(std::launch::async,Y(),1.2); ?--- ①運行新線程auto f7=std::async(std::launch::deferred,baz,std::ref(x)); ?--- ②在wait()或get()內(nèi)部運行任務(wù)函數(shù) auto f8=std::async( ?--- std::launch::deferred | std::launch::async,baz,std::ref(x)); auto f9=std::async(baz,std::ref(x)); ?--- ③交由實現(xiàn)自行選擇運行方式 f7.wait(); ?--- ④前面②處的任務(wù)函數(shù)調(diào)用被延后,到這里才運行總結(jié)
以上是生活随笔為你收集整理的std::future ---C++17 多线程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Syncd - 开源自动化部署工具
- 下一篇: 获取摄像机,摄像机切换Learn Unr