C++11標(biāo)準(zhǔn)庫增加了獲取線程返回值的方法,頭文件為<future>,主要包括future
、promise
、packaged_task
、async
四個(gè)類。
那么,了解一下各個(gè)類的構(gòu)成以及功能。
1 future
future是一個(gè)模板類,它是傳輸線程返回值(也稱為共享狀態(tài))的媒介,也可以理解為線程返回的結(jié)果就安置在future中。
future |
版本:C++11????? 頭文件<future > |
構(gòu)造函數(shù) |
默認(rèn)構(gòu)函數(shù),是一個(gè)無效
|
析構(gòu)函數(shù) | ~future();
|
get | std::future<T>? T get(); 獲取共享狀態(tài),如果共享狀態(tài)尚未就緒(比如線程未結(jié)束),則堵塞,等效于wait函數(shù)。 |
valid | bool valid() const noexcept; 判斷future是否有效。無效future有三種情況:一是使用默認(rèn)構(gòu)造函數(shù)創(chuàng)建的;調(diào)用過移動(dòng)構(gòu)造函數(shù);三是調(diào)用過get函數(shù)。 |
wait | void wait() const; 獲取共享狀態(tài),如果共享狀態(tài)尚未就緒(比如線程未結(jié)束),則堵塞;阻塞結(jié)束之后,還需要繼續(xù)調(diào)用get才能獲取共享狀態(tài),此時(shí)get不再阻塞。 |
wait_for | 設(shè)置最大阻塞時(shí)間 |
wait_until | 設(shè)置最大阻塞時(shí)刻 |
跟多線程相關(guān)的類,大多都有一個(gè)特點(diǎn),就是禁用拷貝構(gòu)造函數(shù),僅能使用移動(dòng)構(gòu)造函數(shù)。
單獨(dú)使用future依然沒有辦法獲取線程的返回值,必須與promise、packaged_task或者async搭配使用。而且,單獨(dú)創(chuàng)建出來的future對(duì)象甚至都沒有意義,必須從promise、packaged_task或者async中創(chuàng)建,才有意義。
2 promise
promise對(duì)象可以看做是future類的封裝,它可以原子的修改future的共享狀態(tài)。
promise |
C++ 11??????????????????頭文件: <future > |
構(gòu)造函數(shù) |
默認(rèn)構(gòu)造函數(shù),構(gòu)造一個(gè)共享狀態(tài)為空的
移動(dòng)構(gòu)造函數(shù),用原屬
|
get_future |
獲取共享狀態(tài),返回一個(gè) |
set_value |
原子地存儲(chǔ) value 到共享狀態(tài),并令狀態(tài)就緒(future::get結(jié)束阻塞 )。 |
set_value_at_thread_exit |
原子地存儲(chǔ) value 到共享狀態(tài),而不立即令狀態(tài)就緒。在當(dāng)前線程退出時(shí),再令狀態(tài)就緒。 |
#include <thread>
#include <future>
#include <iostream>
void fun1(std::promise<int> pro) {
std::this_thread::sleep_for(std::chrono::seconds(3));
pro.set_value(100);
return;
};
int main()
{
std::promise<int> pro;
std::future<int> fut = pro.get_future();
std::thread th(&fun1, std::move(pro));
th.detach();
std::cout << fut.get() << std::endl;
}
需要注意的一點(diǎn)是,future的模板類型與線程函數(shù)的返回類型無關(guān)。上邊f(xié)un1函數(shù)的返回值為void,但是future類型為int。
3 packaged_task
packaged_task是一個(gè)類,它主要包含了一個(gè)future對(duì)象和一個(gè)任務(wù),這個(gè)任務(wù)可以是
函數(shù)、 lambda
表達(dá)式、 bind
表達(dá)式或其他函數(shù)對(duì)象。
packaged_task |
C++11????? ????????????????頭文件: <future > |
構(gòu)造函數(shù) |
|
get_future |
獲取共享狀態(tài),返回一個(gè) |
()運(yùn)算符 |
以 |
#include <iostream>
#include <cmath>
#include <thread>
#include <future>
#include <functional>
// 避免對(duì) std::pow 重載集消歧義的獨(dú)有函數(shù)
int f(int x, int y) { return std::pow(x,y); }
void task_lambda()
{
std::packaged_task<int(int,int)> task([](int a, int b) {
return std::pow(a, b);
});
std::future<int> result = task.get_future();
task(2, 9);
std::cout << "task_lambda:\t" << result.get() << '\n';
}
void task_bind()
{
std::packaged_task<int()> task(std::bind(f, 2, 11));
std::future<int> result = task.get_future();
task();
std::cout << "task_bind:\t" << result.get() << '\n';
}
void task_thread()
{
std::packaged_task<int(int,int)> task(f);
std::future<int> result = task.get_future();
std::thread task_td(std::move(task), 2, 10);
task_td.join();
std::cout << "task_thread:\t" << result.get() << '\n';
}
int main()
{
task_lambda();
task_bind();
task_thread();
}
輸出:
?與promise不同的是,packaged_task任務(wù)的返回類型就是future的類型。
4 async
async是一個(gè)模板函數(shù),它綜合了前邊promise和packaged_task的功能,一個(gè)函數(shù)就可以實(shí)現(xiàn)線程創(chuàng)建、任務(wù)執(zhí)行、獲取返回值等功能。
文章來源:http://www.zghlxwxcb.cn/news/detail-434563.html
async的返回值是一個(gè)future對(duì)象,async所執(zhí)行的任務(wù)完成后,會(huì)令共享狀態(tài)
進(jìn)入就緒狀態(tài)。文章來源地址http://www.zghlxwxcb.cn/news/detail-434563.html
#include <thread>
#include <future>
#include <iostream>
#include <unistd.h>
int main()
{
auto ff = std::async(std::launch::async, []{ sleep(2); return 2.3; });
std::cout << ff.get() << std::endl;
}
到了這里,關(guān)于C++ 多線程編程(三) 獲取線程的返回值——future的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!