1. 程式人生 > >C++11之std::promise使用介紹

C++11之std::promise使用介紹

在C++11中有個future標頭檔案,在這個標頭檔案有一個promise類模板,std::promise 提供儲存值或異常的設施,之後通過 std::promise 物件所建立的 std::future 物件非同步獲得結果。其模板宣告如下:

template< class R > 
class promise;1) //空模板

template< class R > 
class promise<R&>;//非 void 特化,用於線上程間交流物件

template<>          
class promise<void>;//void 特化,用於交流無狀態事件

每個 promise 與共享狀態關聯,共享狀態含有一些狀態資訊和可能仍未求值的結果,非void特化型別的promise,其型別R就是執行緒間交流物件的型別;

promise/future一般是配對使用的,其中:

  • promise是 promise-future 交流通道的“推”端,它可以在某一時刻設定共享狀態的值,通過promise的set系列函式進行設定。

  • future 物件可以非同步返回共享狀態的值,或者在必要的情況下阻塞呼叫者並等待共享狀態標誌變為 ready,然後才能獲取共享狀態的值。

示例

下面演示了通過promise/future對,進行執行緒間交流,一個執行緒用於設定共享狀態,另一個執行緒用於獲取共享狀態結果,程式碼示例如下:

#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <chrono>
#include <future>
#include <mutex>
using namespace std;

typedef struct 
{
   string   strName;
   string   strAdd;
   float    fResult;
}STRU_STUDENT_INFO;

std::mutex g_mut;


//get operate 
void get_val (std::promise<STRU_STUDENT_INFO>& promise) { this_thread::sleep_for(chrono::seconds(1)); try { //enter set_val thread; g_mut.lock(); cout << "enter get thread: " << std::this_thread::get_id() << "\n"; g_mut.unlock(); //通過futur物件來獲取共享狀態中的值 future<STRU_STUDENT_INFO> fut = promise.get_future(); //阻塞獲取,只能get 一次 STRU_STUDENT_INFO x = fut.get(); std::cout << "You entered " << " name :" << x.strName << "\taddr:" << x.strAdd << "\tresult: " << x.fResult << '\n'; } catch (...) { std::cout << "[exception caught]"; } } //set operate void set_val(std::promise<STRU_STUDENT_INFO>& pro) { this_thread::sleep_for(chrono::seconds(1)); STRU_STUDENT_INFO student; student.strName = "jinxiang"; student.strAdd = "fuzhou"; student.fResult = 92.1; //enter set_val thread; g_mut.lock(); cout << "enter set thread: " << std::this_thread::get_id() << "\n"; g_mut.unlock(); //設定共享狀態值,實現執行緒間狀態交流 pro.set_value(student); } int main(int argc, char *argv[]) { promise<STRU_STUDENT_INFO> promise; //利用promise和future完成對執行緒間通訊 thread th1(get_val, ref(promise)); thread th2(set_val, ref(promise)); th1.join(); th2.join(); return 0; }

執行結果:

enter get thread: 140354130814720
enter set thread: 140354122422016
You entered  name :jinxiang addr:fuzhou result: 92.1

promise不支援拷貝構造,只能進行移動操作,例如

promise<int> p1;
//ok
promise<int> p2 = std::move(p1);
//error
promise<int> p3 = p2;

總結

類模板promise通過promise/future對完成對共享狀態的設定和獲取,可用於執行緒間物件交流,物件的型別就是promise的模板引數。