std::future ---C++17 多线程
std::future —C++17 多線程
std::future
C++標準程序庫使用future來模擬這類一次性事件:若線程需等待某個特定的一次性事件發生,則會以恰當的方式取得一個future,它代表目標事件;接著,該線程就能一邊執行其他任務(光顧機場茶座),一邊在future上等待;同時,它以短暫的間隔反復查驗目標事件是否已經發生(查看出發時刻表)。這個線程也可以轉換運行模式,先不等目標事件發生,直接暫緩當前任務,而切換到別的任務,及至必要時,才回頭等待future準備就緒。future可能與數據關聯(如航班的登機口),也可能未關聯。一旦目標事件發生,其future即進入就緒狀態,無法重置。
總之,先保存一個事件(創建future對象),在未來獲取事件的結果(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 << "結束任務\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()); }創建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"); ?--- ①調用p->foo(42,"hello"),其中p的值是&x,即x的地址 auto f2=std::async(&X::bar,x,"goodbye"); ?--- ②調用tmpx.bar("goodbye"),其中tmpx是x的副本 struct Y {double operator()(double); }; Y y; auto f3=std::async(Y(),3.141); ?--- ③調用tmpy(3.141)。其中,由Y()生成一個匿名變量,傳遞給std::async(),進而發生移動構造。在std::async()內部產生對象tmpy,在tmpy上執行Y::operator()(3.141) auto f4=std::async(std::ref(y),2.718); ?--- ④調用y(2.718) X baz(X&); std::async(baz,std::ref(x)); ?--- ⑤調用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()); ?--- ⑥調用tmp(),其中tmp等價于std::move (move_only()),它的產生過程與③相似按默認情況下,std::async()的具體實現會自行決定——等待future時,是啟動新線程,還是同步執行任務。大多數情況下,我們正希望如此。不過,我們還能夠給std::async()補充一個參數,以指定采用哪種運行方式。參數的類型是std::launch,其值可以是std::launch::deferred或std::launch::async。前者指定在當前線程上延后調用任務函數,等到在future上調用了wait()或get(),任務函數才會執行;后者指定必須另外開啟專屬的線程,在其上運行任務函數。該參數的值還可以是std::launch::deferred | std::launch:: async,表示由std::async()的實現自行選擇運行方式。最后這項是參數的默認值。若延后調用任務函數,則任務函數有可能永遠不會運行。舉例如下。
auto f6=std::async(std::launch::async,Y(),1.2); ?--- ①運行新線程auto f7=std::async(std::launch::deferred,baz,std::ref(x)); ?--- ②在wait()或get()內部運行任務函數 auto f8=std::async( ?--- std::launch::deferred | std::launch::async,baz,std::ref(x)); auto f9=std::async(baz,std::ref(x)); ?--- ③交由實現自行選擇運行方式 f7.wait(); ?--- ④前面②處的任務函數調用被延后,到這里才運行總結
以上是生活随笔為你收集整理的std::future ---C++17 多线程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Syncd - 开源自动化部署工具
- 下一篇: 色彩构成(Interaction of