[編程基礎] C++多線程入門8-從線程返回值

原始C++標準僅支持單線程編程。新的C++標準(稱爲C++11或C++0x)於2011年發佈。在C++11中,引入了新的線程庫。因此運行本文程序需要C++至少符合C++11標準。

8 從線程返回值

8.1 使用說明

一個std::future對象可以與asych,std::packaged_task和std::promise一起使用。本文將主要關注將std::future與std::promise對象一起使用。很多時候,我們遇到希望線程返回結果的情況。現在的問題是如何做到這一點?
讓我們舉個例子假設在我們的應用程序中,我們創建了一個將壓縮給定文件夾的線程,並且我們希望該線程返回新的zip文件名及其結果。現在,我們有兩種方法:
使用指針在線程之間共享數據

將指針傳遞給新線程,此線程將設置其中的數據。在此之前,在主線程中使用條件變量繼續等待。當新線程設置數據並向條件變量發送信號時,主線程將喚醒並從該指針獲取數據。爲了簡單起見,我們使用了一個條件變量,一個互斥鎖和一個指針(即3個項)來捕獲返回的值。爲那麼問題將變得更加複雜。有沒有一個簡單的方法從線程返回值。答案是肯定的,使用std::future,讓我們看看下一個解決方案。

C++11方式:使用std::future和std::promise

std::future是一個類模板,其對象存儲將來的值。那麼這future模板有什麼用?實際上,一個std::future對象在內部存儲了將來將分配的值,並且還提供了一種訪問該值的機制,即使用get()成員函數。但是,如果有人嘗試在get()函數可用之前訪問future的此關聯值,則get()函數將阻塞直到該值不可用。
std::promise也是一個類模板,其對象承諾將來會設置該值。每個std::promise對象都有一個關聯的std::future對象,一旦std::promise對象設置了該值,它將給出該值。一個std::promise對象與其關聯的std::future對象共享數據。讓我們一步一步來看看,在Thread1中創建一個std::promise對象。

std::promise<int> promiseObj;

截至目前,該promise對象沒有任何關聯值。但是它提供了一個保證,肯定有人會在其中設置值,一旦設置了值,您就可以通過關聯的std::future對象獲得該值。但是現在假設線程1創建了這個promise對象並將其傳遞給線程2對象。現在,線程1如何知道何時線程2將在此promise對象中設置值?
答案是使用std::future對象。每個std::promise對象都有一個關聯的std::future對象,其他對象可以通過該對象獲取promise設置的值。
現在,線程1將把promiseObj傳遞給線程2。然後線程1將通過std::future的get函數獲取線程2在std::promise中設置的值。

	int val = futureObj.get();

但是,如果線程2尚未設置值,則此調用將被阻塞,直到線程2在promise對象中設置值,即

	promiseObj.set_value(45);

在下圖中查看完整流程:

在這裏插入圖片描述

讓我們看一個完整的std::future和std::promise示例,

#include <iostream>
#include <thread>
#include <future>
void initiazer(std::promise<int> * promObj)
{
    std::cout<<"Inside Thread"<<std::endl;     promObj->set_value(35);
}
int main()
{
    std::promise<int> promiseObj;
    std::future<int> futureObj = promiseObj.get_future();
    std::thread th(initiazer, &promiseObj);
    std::cout<<futureObj.get()<<std::endl;
    th.join();
    return 0;
}

輸出爲:

Inside Thread
35

此外,如果您希望線程在不同的時間點返回多個值,則只需在線程中傳遞多個std::promise對象,然後從關聯的多個std::future對象中獲取多個返回值。在下一篇文章中,我們將看到如何將std::future與std::asych和std::packaged_task結合使用。

8.2 參考

https://thispointer.com//c11-multithreading-part-8-stdfuture-stdpromise-and-returning-values-from-thread/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章