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

4378 ワード

一、std::promise紹介
std::promise
C++11同時プログラミングでよく使われるクラスで、std::futureとよく組み合わせて使用されます.1つのスレッドt 1にタイプtypename Tの値を保存し、バインドされたstd::futureオブジェクトを別のスレッドt 2で取得する役割を果たす.
二、コード例:
以下では、std::promiseの使用方法について、いくつかの簡単な例を通じて徐々に深く理解します.
例1:
#include 
#include 
#include 

void Thread_Fun1(std::promise &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 &f)
{
	//    ,        std::promise       
	auto iVal = f.get();		//iVal = 233

	std::cout << "    (int):" << iVal << std::endl;
}

int main()
{
	//    std::promise  pr1,        int
	std::promise pr1;
	//    std::future  fu1,   std::promise get_future()   pr1  
	std::future 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オブジェクトfu 1は、まずstd::promiseの関数get_を介してfuture()はstd::promiseオブジェクトpr 1にバインドされ、pr 1はスレッドt 1にset_を通過するvalue()は共有データを転送し、fu 1はスレッドt 2でブロック関数get()によって転送されたデータを取得する.
例1で入力したデータ型はintであり,std::promiseはtypename Tのデータを保存できるが,関数ポインタを保存できるか.答えは可能です.例を見てください.
例2:
#include 
#include 
#include 
#include 

//        T
using T = std::function;		//   typedef std::function T;

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

void Thread_Fun1(std::promise &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 &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 pr1;
	//    std::future  fu1,   std::promise get_future()   pr1  
	std::future 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 
#include 
#include 
#include 

//        F
using F = std::function;		//   typedef std::function 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 &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
void Thread_Fun2(std::future &f, Args&& ...args)
{
	//    ,        std::promise       
	auto fun = f.get();		//fun   Test_Fun

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

	std::cout << "       ,  :" << fResult << std::endl;
}

int main()
{
	//    std::promise  pr1,        int
	std::promise pr1;
	//    std::future  fu1,   std::promise get_future()   pr1  
	std::future 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, std::ref(fu1), 1, 2, std::ref(iVal));

	//       
	t1.join();
	t2.join();

	//  iVal    233

	return 1;
}

コードの例を見て、std::promiseはとても面白くて、C++11はとても面白いですか?2333333