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

[C++11]std::promise介紹及使用

一、std::promise介紹

std::promiseC++11併發程式設計中常用的一個類,常配合std::future使用。其作用是在一個執行緒t1中儲存一個型別typename T的值,可供相繫結的std::future物件在另一執行緒t2中獲取。 二、程式碼示例: 下面我們通過幾個簡單小例子逐漸深入瞭解std::promise的使用方法。 示例1:
#include <iostream>
#include <future>
#include <chrono>

void Thread_Fun1(std::promise<int> &p)
{
	//為了突出效果,可以使執行緒休眠5s
	std::this_thread::sleep_for(std::chrono::seconds(5));

	int iVal = 233;
	std::cout << "傳入資料(int):" << iVal << std::endl;

	//傳入資料iVal
	p.set_value(iVal);
}

void Thread_Fun2(std::future<int> &f)
{
	//阻塞函式,直到收到相關聯的std::promise物件傳入的資料
	auto iVal = f.get();		//iVal = 233

	std::cout << "收到資料(int):" << iVal << std::endl;
}

int main()
{
	//宣告一個std::promise物件pr1,其儲存的值型別為int
	std::promise<int> pr1;
	//宣告一個std::future物件fu1,並通過std::promise的get_future()函式與pr1繫結
	std::future<int> fu1 = pr1.get_future();

	//建立一個執行緒t1,將函式Thread_Fun1及物件pr1放線上程裡面執行
	std::thread t1(Thread_Fun1, std::ref(pr1));
	//建立一個執行緒t2,將函式Thread_Fun2及物件fu1放線上程裡面執行
	std::thread t2(Thread_Fun2, std::ref(fu1));

	//阻塞至執行緒結束
	t1.join();
	t2.join();

	return 1;
}

可以看到std::future物件fu1先是通過std::promise的函式get_future()與std::promise物件pr1相繫結,pr1線上程t1中通過set_value()傳入共享資料,fu1線上程t2中通過阻塞函式get()獲取到傳入的資料。
示例1中傳入的資料型別是int,前面介紹中說std::promise可以儲存typename T的資料,那麼可以儲存函式指標嗎?答案是可行的,請看示例。 示例2:
#include <iostream>
#include <future>
#include <chrono>
#include <functional>

//宣告一個可調物件T
using T = std::function<int(int)>;		//等同於typedef std::function<int(int)> T;

int Test_Fun(int iVal)
{
	std::cout << "Value is:" << iVal << std::endl;
	return iVal + 232;
}

void Thread_Fun1(std::promise<T> &p)
{
	//為了突出效果,可以使執行緒休眠5s
	std::this_thread::sleep_for(std::chrono::seconds(5));

	std::cout << "傳入函式Test_Fun" << std::endl;

	//傳入函式Test_Fun
	p.set_value(std::bind(&Test_Fun, std::placeholders::_1));
}

void Thread_Fun2(std::future<T> &f)
{
	//阻塞函式,直到收到相關聯的std::promise物件傳入的資料
	auto fun = f.get();		//iVal = 233

	int iVal = fun(1);

	std::cout << "收到函式並執行,結果:" << iVal << std::endl;
}

int main()
{
	//宣告一個std::promise物件pr1,其儲存的值型別為int
	std::promise<T> pr1;
	//宣告一個std::future物件fu1,並通過std::promise的get_future()函式與pr1繫結
	std::future<T> fu1 = pr1.get_future();

	//建立一個執行緒t1,將函式Thread_Fun1及物件pr1放線上程裡面執行
	std::thread t1(Thread_Fun1, std::ref(pr1));
	//建立一個執行緒t2,將函式Thread_Fun2及物件fu1放線上程裡面執行
	std::thread t2(Thread_Fun2, std::ref(fu1));

	//阻塞至執行緒結束
	t1.join();
	t2.join();

	return 1;
}

既然可以傳函式物件,那麼是否可以通過模板魔改,傳入可變元函式?請看示例。 示例3:
#include <iostream>
#include <future>
#include <chrono>
#include <functional>

//宣告一個可調物件F
using F = std::function<int(int, int, int&)>;		//等同於typedef std::function<int(int, int, int&)> F;

//函式可以改成任意引數,任意返回型別
int Test_Fun(int a, int b, int &c)
{
	//a = 1, b = 2
	c = a + b + 230;
	return c;
}

void Thread_Fun1(std::promise<F> &p)
{
	//為了突出效果,可以使執行緒休眠5s
	std::this_thread::sleep_for(std::chrono::seconds(5));

	std::cout << "傳入函式Test_Fun" << std::endl;

	//傳入函式Test_Fun
	p.set_value(std::bind(&Test_Fun, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
}

template<typename T, typename ...Args>
void Thread_Fun2(std::future<T> &f, Args&& ...args)
{
	//阻塞函式,直到收到相關聯的std::promise物件傳入的資料
	auto fun = f.get();		//fun等同於Test_Fun

	auto fResult = fun(std::forward<Args>(args)...);

	std::cout << "收到函式並執行,結果:" << fResult << std::endl;
}

int main()
{
	//宣告一個std::promise物件pr1,其儲存的值型別為int
	std::promise<F> pr1;
	//宣告一個std::future物件fu1,並通過std::promise的get_future()函式與pr1繫結
	std::future<F> fu1 = pr1.get_future();

	//宣告一個變數
	int iVal = 0;

	//建立一個執行緒t1,將函式Thread_Fun1及物件pr1放線上程裡面執行
	std::thread t1(Thread_Fun1, std::ref(pr1));
	//建立一個執行緒t2,將函式Thread_Fun2及物件fu1放線上程裡面執行
	std::thread t2(Thread_Fun2<F, int, int, int&>, std::ref(fu1), 1, 2, std::ref(iVal));

	//阻塞至執行緒結束
	t1.join();
	t2.join();

	//此時iVal的值變成233

	return 1;
}

看完程式碼示例,是不是感覺std::promise很有趣,C++11很有趣?2333333

相關推薦

[C++11]std::promise介紹使用

一、std::promise介紹 std::promise是C++11併發程式設計中常用的一個類,常配合std::future使用。其作用是在一個執行緒t1中儲存一個型別typename T的值,可供

c++ 11 std::promise std::future

Std::promise 是一個類 std::future也是一個類 std::future<bool>futObj 表示一個儲存bool值的future類物件。 std::promise<bool> proObj表示promise的一個類物件叫proObj,該物件儲存了一個

C++11 併發指南四( 詳解一 std::promise 介紹)

前面兩講《C++11 併發指南二(std::thread 詳解)》,《C++11 併發指南三(std::mutex 詳解)》分別介紹了 std::thread 和 std::mutex,相信讀者對 C++11 中的多執行緒程式設計有了一個最基本的認識,本文將介紹 C++11 標準中 <future>

C++11 併發指南四( 詳解一 std::promise 介紹)

前面兩講《C++11 併發指南二(std::thread 詳解)》,《C++11 併發指南三(std::mutex 詳解)》分別介紹了 std::thread 和 std::mutex,相信讀者對 C++11 中的多執行緒程式設計有了一個最基本的認識,本文將介紹 C++

C++11 std::unique_lock與std::lock_guard區別多執行緒應用例項

C++多執行緒程式設計中通常會對共享的資料進行防寫,以防止多執行緒在對共享資料成員進行讀寫時造成資源爭搶導致程式出現未定義的行為。通常的做法是在修改共享資料成員的時候進行加鎖--mutex。在使用鎖的時候通常是在對共享資料進行修改之前進行lock操作,在寫完之後再進行unl

C++11 std::chrono庫詳解

toolbar space max mil exp 值類型 cond 精度 ++i 所謂的詳解只不過是參考www.cplusplus.com的說明整理了一下,因為沒發現別人有詳細講解。   chrono是一個time library, 源於boost,現在已經是C++標準。

c++11 std::chrono

nbsp begin point duration argc ios iomanip poi count() #include <iostream> #include <iomanip> #include <ctime> #inclu

C++ 11常見功能介紹:auto,decltype,nullptr,for,lambda

參數 out -i 定義 _each 容器 初始 process 初始化 什麽是C++11 C++11是曾經被叫做C++0x,是對目前C++語言的擴展和修正,C++11不僅包含核心語言的新機能,而且擴展了C++的標準程序庫(STL),並入了大部分的C++ Technical

C++11 std::function

一 定義 標頭檔案<funticonal> 先來看一段話 Class template std::function is a general-purpose polymorphic function wrapper. Instances of std::funct

C++11 std::bind

一 宣告 標頭檔案<functional> template< class F, class... Args > /*unspecified*/ bind( F&& f, Args&&... args ); template<

C語言操作符的介紹總結

一、操作符的定義       簡單來說操作符就是告訴編譯程式執行特定數學運算,邏輯運算,位運算的符號。 二、操作符的分類       算數操作符    &

c++11:std::copy示例

c++11的<algorithm>庫提供了很多基礎有用的模板函式。以std::copy為例,下面的程式碼將容器(list)中的字串按行輸出到指定的檔案,只要2行程式碼: #include <algorithm> #include <fstream>

c++11 std::future和std::async

std::future可以從非同步任務中獲取結果,一般與std::async配合使用,std::async用於建立非同步任務,實際上就是建立一個執行緒執行相應任務。    使用程式碼如下: #include <future> #include <iostre

c++11 std::ref使用場景

C++本身有引用(&),為什麼C++11又引入了std::ref? 主要是考慮函數語言程式設計(如std::bind)在使用時,是對引數直接拷貝,而不是引用。如下例子: #include <functional> #include <iostream> vo

c++11 - std::unique_ptr

前言 std::unique_ptr是c++11中的智慧指標 看到cppreference上有個demo, 自己過一遍。 c++11中的lambda表示式感覺比較晦澀. 實驗 實驗環境: vs2017 // @file main.cpp // @brief test std:

C++11 std::packaged_task的妙用

std::packaged_task簡介 std::packaged_task是C++11開始加入到STL(Standard Template Libarary, 標準模板庫)的併發程式設計工具,位於

c++11 std::async

template< class Function, class... Args > std::future<std::invoke_result_t<std::decay_t<Function>, std::decay_t<Args&

C/C++大數運算庫介紹安裝

在網路安全技術領域中各種加密解密演算法的軟體實現上始終有一個共同的問題就是如何在普通的PC機上實現大數的運算。眾所周知,我們現在日常生活中所普遍應用的計算機,即我們通常所說的PC機個人電腦大部分的機器內部字長還是32位的,最近才開始向64位的字長過渡,但是在各種加密解密的演算法中為了達到一定的安

c++11 std::async使用注意

    std::async,c++11中提供的非同步任務高階抽象,包含在 <future>標頭檔案中,能讓你方便的實現非同步地執行一個任務 並在需要地時候獲取其結果。和直接使用std::thread 相比,有著一些優勢:   1.std::async 返回的f

Linux C Socket UDP程式設計介紹例項

1、UDP網路程式設計主要流程 UDP協議的程式設計框架,客戶端和伺服器之間的差別在於伺服器必須使用bind()函式來繫結偵聽的本地UDP埠,而客戶端則可以不進行繫結,直接傳送到伺服器地址的某個埠地址。框圖如圖1.3所示 UDP協議的伺服器端流程 伺服器流程主要分為下述6個