C++11多线程之future和promise
std::future和promise的作用是在不同線程之間傳遞數(shù)據(jù)。使用指針也可以完成數(shù)據(jù)的傳遞,但是指針非常危險,因為互斥量不能阻止指針的訪問;而且指針的方式傳遞的數(shù)據(jù)是固定的,如果更改數(shù)據(jù)類型,那么還需要更改有關的接口,比較麻煩;promise支持泛型的操作,更加方便編程處理。
假設線程1需要線程2的數(shù)據(jù),那么組合使用方式如下:
線程1初始化一個promise對象和一個future對象,promise傳遞給線程2,相當于線程2對線程1的一個承諾;future相當于一個接受一個承諾,用來獲取未來線程2傳遞的值
線程2獲取到promise后,需要對這個promise傳遞有關的數(shù)據(jù),之后線程1的future就可以獲取數(shù)據(jù)了。
如果線程1想要獲取數(shù)據(jù),而線程2未給出數(shù)據(jù),則線程1阻塞,直到線程2的數(shù)據(jù)到達。
std::future對象可以和asych,std::packaged_task,std::promise一起使用。這篇文章集中討論std::future和std::promise。
我們經(jīng)常會遇到需要得到線程返回結果的情況,現(xiàn)在的問題是我們?nèi)绾螌崿F(xiàn)。
舉個例子:
假設在程序中,我們創(chuàng)建了一個壓縮給定文件夾的線程,并且我們希望該線程能夠返回新的zip文件的名稱和大小。
有兩種實現(xiàn)方式:
1、老方法:使用指針在線程間共享數(shù)據(jù)
傳遞一個指針到新的線程中,該線程將在其中設置數(shù)據(jù)。直到主線程繼續(xù)等待使用條件變量。當新線程設置數(shù)據(jù)并通知條件變量時,主線程將喚醒并從該指針處獲取數(shù)據(jù)。
為了實現(xiàn)這一簡單功能,我們使用了一個條件變量、一個mutex鎖和一個指針,來實現(xiàn)捕獲返回值。
如果我們想要該線程在不同的時間點返回3個不同的值,問題會變得更加復雜,有沒有一種簡單的方法來從線程處獲取返回值呢?
答案是使用std::future
2、c++11的方法:使用std::future 和 std::promise
std::future是一個類模板(class template),其對象存儲未來的值,
到底什么是未來的值呢?
事實上,一個std::future對象在內(nèi)部存儲一個將來會被賦值的值,并提供了一個訪問該值的機制,通過get()成員函數(shù)實現(xiàn)。但如果有人視圖在get()函數(shù)可用之前通過它來訪問相關的值,那么get()函數(shù)將會阻塞,直到該值可用。
std::promise也是一個類模板,其對象有可能在將來對值進行賦值,每個std::promise對象有一個對應的std::future對象,一旦由std::promise對象設置,std::future將會對其賦值。
std::promise對象與其管理的std::future對象共享數(shù)據(jù)。逐步解析
在線程1中創(chuàng)建一個std::promise對象
?
目前為止,該promise對象沒有任何管理的值,但它承諾肯定會有人對其進行賦值,一旦被賦值,就可以通過其管理的std::future對象來獲取該值。
但是,假設線程1創(chuàng)建了該promise對象并將其傳給線程2,那么線程1怎樣知道線程2什么時候會對promise對象進行賦值呢?
答案是使用std::future對象
每個std::promise對象都有個對應的std::future對象,其他人可以通過它來獲取promise設置的值。
所以,線程1將會創(chuàng)建std::promise對象,然后在將其傳遞給線程2之前從它那里獲取std::future對象。
現(xiàn)在,線程1將promiseObj傳遞給線程2.
那么線程1將會獲取到線程2通過std::future的get函數(shù)設置在std::promise中的值,
?但是如果線程2還沒有對該值進行設置,那么這個調(diào)用將會阻塞,直到線程2在promise對象中對該值進行設置。
promiseObj.set_value(45);一個簡單的說明流程:
?
簡單的代碼示例:
#include <iostream> #include <functional> #include <future> #include <thread> #include <chrono> #include <cstdlib>void thread_set_promise(std::promise<int>& promiseObj) {std::cout << "In a thread, making data...\n";std::this_thread::sleep_for(std::chrono::milliseconds(1000));promiseObj.set_value(35);std::cout << "Finished\n"; }int main() {std::promise<int> promiseObj;std::future<int> futureObj = promiseObj.get_future();std::thread t(&thread_set_promise, std::ref(promiseObj));std::cout << futureObj.get() << std::endl;t.join();system("pause");return 0; }輸出結果:
如果std::promise對象在賦值之前被銷毀,那么管理的std::future對象上的get()調(diào)用將會拋出異常。
除此之外,如果想要線程在不同時間點返回多個值,只需要在線程中傳輸多個std::promise對象,并從相關的多個std::futur對象中獲取多個返回值。
原文鏈接:
https://blog.csdn.net/lijinqi1987/article/details/78507623
https://blog.csdn.net/qq_35976351/article/details/84186042
總結
以上是生活随笔為你收集整理的C++11多线程之future和promise的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 马粉心伤:曝长安马自达将停产阿特兹、CX
- 下一篇: 博通第一财季营收 89.15 亿美元,净