自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Thread、Future、Promise、Packaged_task、Async之間有什么關(guān)系?

開發(fā) 前端
一個(gè)promise的set_value()只能調(diào)用一次,如果調(diào)用多次,就會throw exception,如果外部沒catch exception,程序就會crash。

并發(fā)編程一般指多線程編程,C++11之后關(guān)于多線程編程有幾個(gè)高級API:

  • std::thread
  • std::future
  • std::shared_future
  • std::promise
  • std::packaged_task
  • std::async

可能很多人都搞不清楚它們之前有什么聯(lián)系,可以直接看這張圖:

圖片

從這張圖我們可以大體看出來:

  • packaged_task ≈ promise + function
  • async ≈ thread + packaged_task
  • 通過promise的get_future()可拿到future
  • 通過future的share()可拿到shared_future

promise和future是線程之間的同步通道,類似于條件變量的封裝,看它的使用:

#include <future>
#include <iostream>
#include <thread>

int main() {
std::promise<bool> prom;
std::future<bool> f = prom.get_future();
prom.set_value(true);
std::cout << f.get() << std::endl;
}

首先創(chuàng)建一個(gè)promise,通過promise可以拿到future,future有wait()和get()等方法,這種方法會阻塞當(dāng)前線程,直到future的源promise調(diào)用了set_value,future的wait()只有阻塞功能,而get()方法不僅有阻塞功能,還能拿到set_value()設(shè)置的值。我舉個(gè)多線程的示例:

#include <future>
#include <iostream>
#include <thread>

int main() {
std::promise<int> prom;
auto f = prom.get_future();
std::thread t(
[](std::promise<int> p) {
std::this_thread::sleep_for(std::chrono::seconds(2));
p.set_value(100);
},
std::move(prom));
std::cout << f.get() << std::endl;
if (t.joinable()) t.join();
}

這段代碼執(zhí)行后會在兩秒后輸出100。這個(gè)結(jié)果就驗(yàn)證了上面啰嗦的promise的future的get()的阻塞和獲取結(jié)果的能力。

注意:一個(gè)promise的set_value()只能調(diào)用一次,如果調(diào)用多次,就會throw exception,如果外部沒catch exception,程序就會crash。

promise的阻塞功能還是蠻好用的,我在工程中就經(jīng)常用到它。

介紹完promise,再來看看packaged_task:

#include <future>
#include <iostream>
#include <thread>
int main() {
std::packaged_task<int(int, int)> task([](int a, int b) { return a + b; });
auto f = task.get_future();
std::thread t(std::move(task), 1, 2);
std::cout << f.get() << std::endl;
if (t.joinable()) t.join();
}

可以拿這段代碼和上面那段promise的代碼對比看看,可以得出結(jié)論:packaged_task ≈ promise + function

promise只能set_value,不太好執(zhí)行復(fù)雜的邏輯,有執(zhí)行函數(shù)+阻塞的需求時(shí),就可以考慮使用packaged_task。

可以思考一下,如果要你封裝一個(gè)packaged_task,你會怎么做?

再看async:

#include <future>
#include <iostream>
#include <thread>
int main() {
auto f = std::async(
std::launch::async, [](int a, int b) { return a + b; }, 1, 2);
std::cout << f.get() << std::endl;
}

這里可以看到,使用了async后,連thread都不需要創(chuàng)建了,這也就驗(yàn)證了上面圖中的結(jié)論:async ≈ thread + packaged_task

這里請注意:async中的第一個(gè)參數(shù)我使用的是std::launch::async,只有當(dāng)參數(shù)為std::launch::async時(shí),函數(shù)才會異步執(zhí)行。

參數(shù)還可以是std::launch::deferred,參數(shù)為這個(gè)時(shí),函數(shù)不會異步執(zhí)行,只有當(dāng)對應(yīng)的future調(diào)用了get時(shí),函數(shù)才會執(zhí)行,而且是在當(dāng)前線程執(zhí)行。

關(guān)于async有幾個(gè)坑,我之前寫過一篇文章,可以看這個(gè):async的兩個(gè)坑。

介紹完async,再介紹下shared_future。

普通的future有個(gè)特點(diǎn),它不能拷貝,只能移動,這就意味著只能有一個(gè)線程一個(gè)實(shí)例可以通過get()拿到對應(yīng)的結(jié)果。

如果想要多個(gè)線程多個(gè)實(shí)例拿到結(jié)果,就可以使用shared_future,那怎么拿到shared_future,可以通過普通future的shared()方法。

#include <future>
#include <iostream>
#include <thread>
int main() {
std::promise<int> prom;
auto fu = prom.get_future();
auto shared_fu = fu.share();
auto f1 = std::async(std::launch::async, [shared_fu]() { std::cout << shared_fu.get() << std::endl; });
auto f2 = std::async(std::launch::async, [shared_fu]() { std::cout << shared_fu.get() << std::endl; });
prom.set_value(102);
f1.get();
f2.get();
}

看到這里,大家應(yīng)該明白thread、future、promise、packaged_task、async之間的關(guān)系了吧。

責(zé)任編輯:武曉燕 來源: 程序喵大人
相關(guān)推薦

2020-02-27 08:52:51

NFVSDN網(wǎng)絡(luò)

2021-10-18 10:17:07

Go Golang語言

2015-08-03 10:20:39

大數(shù)據(jù)Hadoop

2022-11-01 15:02:11

2023-11-02 09:59:53

C++設(shè)計(jì)模式

2019-09-29 19:28:13

區(qū)塊鏈比特幣加密貨幣

2021-04-27 10:14:28

大數(shù)據(jù)物聯(lián)網(wǎng)IOT

2015-08-27 14:05:01

大數(shù)據(jù)創(chuàng)業(yè)

2024-04-02 08:02:11

Dockerk8s容器

2022-02-14 11:28:51

區(qū)塊鏈元宇宙代幣

2021-07-20 08:12:55

CPU核數(shù)線程數(shù)

2021-02-02 12:46:36

Spring異步循環(huán)

2019-03-12 11:12:50

大數(shù)據(jù)HadoopSpark

2023-04-06 11:54:55

2024-03-10 21:00:33

2022-09-13 09:09:37

容器容器云容器化

2023-07-10 10:53:22

2017-12-10 22:19:30

2020-04-30 11:05:50

機(jī)器閱讀人工智能機(jī)器學(xué)習(xí)

2016-07-08 14:41:28

云計(jì)算
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號