Multi thread: std::promise

前面咱們瞭解到可使用std::shared_future/std::shared_future在多個其餘線程中處理另一個線程的函數的返回結果.ios

 

那麼疑問來了,咱們要怎樣在多線程之間傳遞數據呢?promise

demo1 :std::promise在線程之間傳遞參數/處理異常:多線程

#include <iostream>
#include <thread>
#include <chrono>
#include <future>
#include <utility>
#include <exception>
#include <stdexcept>
#include <string>

void doSomething(std::promise<std::string>&  p)
{
	try {
		std::cout << "read char('x' for exception): ";
		char c = std::cin.get();
		if (c == 'x') {
			throw  std::runtime_error(std::string("runtime_error"));
		}

		std::string str = std::string("char ") + c + std::string(" read");
		p.set_value(std::move(str));

		p.set_value(std::string("shihuawoaini"));

	}catch (...) {
		p.set_exception(std::current_exception());

	}
}

int main()
{
	try {
		std::promise<std::string> p;
		std::thread t1(doSomething, std::ref(p)); //注意這裏是以引用的形式傳遞的std::promise對象.
        //只有以引用的形式咱們才能改變std::promise中的shared state的狀態,並且本事std::promise是不支持拷貝的
		t1.detach();

		std::future<std::string> f(p.get_future()); //此時的std::future和前面的std::promise共用同一個shared state;

		std::cout << "result: " << f.get() << std::endl; //注意這裏的get(),當std::future的shared state未被設置爲ready的時候會block mian線程.直到被設置爲ready.

	}catch (const std::exception& e) {
		std::cerr << "EXCEPTION: " << e.what() << std::endl;

	}catch (...) {
		std::cerr << "EXCEPTION: " << std::endl;
	}
}

 最好本身跑一下上面的例子再看下面的內容函數

 

 

在向線程傳遞std::promise對象做爲參數的時候儘可能用std::ref.spa

1,由於std::promise對象是不支持拷貝的.線程

2,只有以by-reference的形式傳遞咱們才能改變原std::promise對象的shared state.指針

std::promise的構造函數:code

1,構造函數在構建std::promise的時候構建一個新的shared state.對象

2,移動構造函數從另外的std::promise對象得到shared state,被移動的std::promise對象再也不具備shared state.內存

std::promise內的shared state存放一個相應類型的值或者異常.

promise(); //默認構造函數.

template <class Alloc> promise (allocator_arg_t aa, const Alloc& alloc);//本身設置內存分配器的構造函數.
	
promise (const promise&) = delete; //拷貝構造函數被刪除掉了. 

promise (promise&& x) noexcept;//移動構造函數.

std::promise::get_future

該函數返回一個std::future對象,且std::future對象與當前std::promise共用一個shared state:

1, 也就是說噹噹前std::promise對象的shared state被設爲ready的時候,被返回出來的std::future對象的shared state也被設置爲ready.

2,也就是說咱們能夠經過被返回的std::future對象得到std::promise中的值和異常.

future<T> get_future();

std::promise::operator=

雖然是operator=可是隻能使用移動賦值運算符.拋棄當前std::promise內的shared state,得到rhs的shared state,且被移動的std::promise對象變成不能使用狀態,不然拋出std::future_error異常.

promise& operator= (promise&& rhs) noexcept;
	
promise& operator= (const promise&) = delete; //拷貝複製運算符被刪除了.

std::promise::set_exception

exception_ptr是一個智能指針,存儲一個指向異常的智能指針到std::promise的shared state,

且當前shared state的狀態會當即被設置爲ready.

void set_exception (exception_ptr p);

std::promise::set_value

設置一個值到存儲到當前std::promise的shared state,且當即將shared state的狀態設置爲ready.

void set_value (const T& val);

void set_value (T&& val);

void promise<R&>::set_value (R& val);   // when T is a reference type (R&)

void promise<void>::set_value (void);   // when T is void

std::promise::set_exception_at_thread_exit

設置一個存儲異常的智能指針存儲到當前std::promise對象的shared state裏,可是並無當即把該shared state設置爲ready,而是直到當前線程完成退出的時才被設置爲ready.

void set_exception_at_thread_exit (exception_ptr p);

std::promise::set_value_at_thread_exit

設置一個值存儲到當前std::promise對象的shared state裏,可是並無當即把該shared sate設置爲ready,而是直到當前線程結束退出的時候才被設置爲ready.

void set_value_at_thread_exit (const T& val);

void set_value_at_thread_exit (T&& val);

void promise<R&>::set_value_at_thread_exit (R& val);     // when T is a reference type (R&)

void promise<void>::set_value_at_thread_exit (void);     // when T is void

總結:

若是咱們經過當前std::promise對象的get_future()獲得一個std::future,因爲是獲得的std::future和當前std::promise對象是共用一個shared state的,所以當咱們想要經過std::future對象的get()得到存儲於shared state狀態中的值的時候,若是這個shared state沒有被設置爲ready,就會阻塞正在調用該std::future對象get()函數的線程.

相關文章
相關標籤/搜索