目錄
-
-
- 前言
- future
- 總結
-
前言
前一篇文章講到了關于
condition_variable
的使用,但是這種方法太過于底層了,不是很方面,而且需要對調用方進行操作。這樣對于程式員來說太過于麻煩,引入一個全新的接口,讓被調用的線程自動進行,調用線程直接調用結果就行。這就是C++引入的
future()類
,而且這種方式可以在不同線程之間傳遞資料。
我們首先假設情況現在有兩個線程,線程A等待線程B執行結果,線程B執行完成之後将結果傳回給線程A。之前在
condition_variable
裡面是線上程外定義一個全局變量,但是這樣會導緻資料不安全有洩露的風險。
future
首先看一個例子:
string fun_1() {
return "123";
}
int main() {
auto x = async(fun_1);
cout << "456";
cout << x.get();
}
此時x擷取到的是
future<string>
類型,然後在調用.get()函數獲得其中包含的值。而且線程
fun_1
隻有在
.get()
時才調用。執行結果如下:
這裡面有兩個函數,一個是
async
,另一個是
future
。
async
使用方法和
thread類
類似,但是多了一個函數參數。
async(A, B, C,....)
:
- 其中這個A:是表示你是否建立一個新線程,參數類型是std::launch類型。
- std::launch::deferred:表示該函數會延遲啟動,直到
上調用future
或wait()
;get()
- std::launch::async:表示該函數必須運作在他自己的線程上;
- std::launch::deferred | std::launch::async:表明該函數可以有具體實作來選擇(預設最後一個);
- std::launch::deferred:表示該函數會延遲啟動,直到
- B和C:分别是需要傳入的函數和函數的參數,和thread一樣,函數的參數是通過副本傳入,如果需要傳入引用則需要使用std::ref類。
future可以從異步任務中擷取結果,一般與std::async配合使用,std::async用于建立異步任務,實際上就是建立一個線程執行相應任務。
- std::future::get擷取結果,如果調用過程中,任務尚未完成,則主線程阻塞至任務完成。
- std::future::wait_for等待結果傳回,wait_for可設定逾時時間,如果在逾時時間之内任務完成,則傳回std::future_status::ready狀态;如果在逾時時間之内任務尚未完成,則傳回std::future_status::timeout狀态。
前面那個例子我們看了get()方法,我們來測試一下這個wait_for()方法:
string fun_2() {
this_thread::sleep_for(chrono::seconds(3));
return "hello";
}
int main() {
auto x = async(fun_2);
cout << "456 ";
if (x.wait_for(chrono::seconds(1)) == future_status::timeout)
cout << "time out" << endl;
else
cout << x.get();
}
線程fun_2執行時,線程睡眠3秒,主線程僅僅隻等待1秒,就會出現傳回time_out标志。
修改相應的等待時間參數之後得到的結果就是另外一個樣子了。
總結
在使用異步線程時,采用future比condition_variable簡單而且無需考慮内部實作的過程。是以在使用是盡量使用這個,而且還可以實作在不同線程之間傳遞資料,避免使用全局變量提高系統安全性。