std::future類模板的定義
template<class _Ty>
class future: public _State_manager<_Ty>
{...}
future繼承自_State_manager,future沒(méi)有任何數(shù)據(jù)成員洽瞬,其內(nèi)存布局與父類一模一樣,為用戶提供的公共接口函數(shù)實(shí)質(zhì)也是通過(guò)繼承 _State_manager的函數(shù)實(shí)現(xiàn)樱蛤。
1. _State_manager分析
_State_manager類模板用來(lái)管理(可能不存在的)關(guān)聯(lián)異步狀態(tài)對(duì)象
私有數(shù)據(jù)成員:
private:
_Associated_state<_Ty> *_Assoc_state;
bool _Get_only_once;
-
_Assoc_state
:指向關(guān)聯(lián)的異步狀態(tài)對(duì)象_Associated_state是一個(gè)線程安全的類壮莹,內(nèi)部通過(guò)互斥鎖和條件變量實(shí)現(xiàn)共享數(shù)據(jù)的安全同步。
這個(gè)類是為c++11高級(jí)同步方式(promise/packeged_task/async)提供了底層支持荣德。
_Get_only_once
:標(biāo)識(shí)關(guān)聯(lián)的狀態(tài)是否只能提取一次(std::future)還是多次(std::shared_future)
構(gòu)造與賦值函數(shù)
//默認(rèn)構(gòu)造函數(shù)闷煤,無(wú)關(guān)聯(lián)的異步狀態(tài),默認(rèn)允許多次提取關(guān)聯(lián)狀態(tài)
_State_manager()
: _Assoc_state(nullptr)
{
_Get_only_once = false;
}
//通過(guò)關(guān)聯(lián)異步狀態(tài)對(duì)象構(gòu)造
_State_manager(_Associated_state<_Ty> *_New_state, bool _Get_once)
: _Assoc_state(_New_state)
{
_Get_only_once = _Get_once;
}
//拷貝構(gòu)造
_State_manager(const _State_manager& _Other, bool _Get_once = false)
: _Assoc_state(nullptr)
{
_Copy_from(_Other);
_Get_only_once = _Get_once;
}
//移動(dòng)構(gòu)造
_State_manager(_State_manager&& _Other, bool _Get_once = false)
: _Assoc_state(nullptr)
{
_Move_from(_Other);
_Get_only_once = _Get_once;
}
//拷貝賦值
_State_manager& operator=(const _State_manager& _Other)
{
_Copy_from(_Other);
return (*this);
}
//移動(dòng)賦值
_State_manager& operator=(_State_manager&& _Other)
{
_Move_from(_Other);
return (*this);
}
拷貝和移動(dòng)的真正實(shí)現(xiàn):
//拷貝_State_manager
void _Copy_from(const _State_manager& _Other)
{ //防止自我拷貝涮瞻、賦值
if (this != _STD addressof(_Other))
{
//先判斷是否有引用的關(guān)聯(lián)狀態(tài)
if (_Assoc_state)
_Assoc_state->_Release();
if (_Other._Assoc_state == nullptr)
_Assoc_state = nullptr;
else
{ //增加_Assoc_state對(duì)象的引用計(jì)數(shù)
_Other._Assoc_state->_Retain();
//拷貝數(shù)據(jù)成員
_Assoc_state = _Other._Assoc_state;
_Get_only_once = _Other._Get_only_once;
}
}
}
//移動(dòng)_State_manager
void _Move_from(_State_manager& _Other)
{
//防止自我移動(dòng)鲤拿、賦值
if (this != _STD addressof(_Other))
{
//先釋放*this的關(guān)聯(lián)狀態(tài)
if (_Assoc_state)
_Assoc_state->_Release();
//將other的關(guān)聯(lián)狀態(tài)轉(zhuǎn)移到*this
_Assoc_state = _Other._Assoc_state;
_Other._Assoc_state = nullptr;
_Get_only_once = _Other._Get_only_once;
}
}
- 不管是從other拷貝還是移動(dòng),都要首先避免自我拷貝署咽、移動(dòng)
- 不管是從other拷貝還是移動(dòng)近顷,都要判斷是否有引用關(guān)聯(lián)對(duì)象
析構(gòu):
//如果有關(guān)聯(lián)的異步對(duì)象,則釋放
~_State_manager() noexcept
{
if (_Assoc_state != nullptr)
_Assoc_state->_Release();
}
狀態(tài):
_NODISCARD bool valid() const noexcept
{
return (_Assoc_state != nullptr
&& !(_Get_only_once && _Assoc_state->_Already_retrieved()));
}
_State_manager狀態(tài)是否有效必須符合:
- 指向關(guān)聯(lián)狀態(tài)的指針有效
- 關(guān)聯(lián)狀態(tài)的值——即異步結(jié)果——是否被提取
- 如果是std::future,則關(guān)聯(lián)狀態(tài)只能被提取一次
- 如果是std::shared_future,則與關(guān)聯(lián)狀態(tài)是否被提取無(wú)關(guān)
等待異步結(jié)果發(fā)生:
這些wait系列函數(shù)是future和shared_future對(duì)應(yīng)的wait系列函數(shù)的真正實(shí)現(xiàn)宁否。
void wait() const
{ // wait for signal
if (!valid())
_Throw_future_error(make_error_code(future_errc::no_state));
_Assoc_state->_Wait();
}
template<class _Rep,
class _Per>
future_status wait_for(const chrono::duration<_Rep, _Per>& _Rel_time) const
{ // wait for duration
if (!valid())
_Throw_future_error(make_error_code(future_errc::no_state));
return (_Assoc_state->_Wait_for(_Rel_time));
}
template<class _Clock,
class _Dur>
future_status wait_until(const chrono::time_point<_Clock, _Dur>& _Abs_time) const
{ // wait until time point
if (!valid())
_Throw_future_error(make_error_code(future_errc::no_state));
return (_Assoc_state->_Wait_until(_Abs_time));
}
提取和設(shè)置異步狀態(tài)結(jié)果
//提取關(guān)聯(lián)狀態(tài)的結(jié)果---for future::get()/shared_future::get()
_Ty& _Get_value() const
{
if (!valid())
_Throw_future_error(
make_error_code(future_errc::no_state));
return (_Assoc_state->_Get_value(_Get_only_once));
}
//設(shè)置關(guān)聯(lián)狀態(tài)的結(jié)果---for promise::set_value()
void _Set_value(const _Ty& _Val, bool _Defer)
{
if (!valid())
_Throw_future_error(
make_error_code(future_errc::no_state));
_Assoc_state->_Set_value(_Val, _Defer);
}
void _Set_value(_Ty&& _Val, bool _Defer)
{
if (!valid())
_Throw_future_error(
make_error_code(future_errc::no_state));
_Assoc_state->_Set_value(_STD forward<_Ty>(_Val), _Defer);
}
2. std::future分析
future類定義不可復(fù)制異步返回對(duì)象(_State_manager管理(可能不存在的)關(guān)聯(lián)異步狀態(tài)對(duì)象)
future無(wú)任何私有數(shù)據(jù)成員窒升,其提供的接口都是調(diào)用父類 _State_manager的函數(shù)實(shí)現(xiàn)。
構(gòu)造家淤、賦值异剥、析構(gòu)
using _Mybase = _State_manager<_Ty>;
...
//默認(rèn)構(gòu)造
future() noexcept
{
}
//移動(dòng)構(gòu)造--調(diào)用父類的移動(dòng)構(gòu)造
future(future&& _Other) noexcept
: _Mybase(_STD move(_Other), true)//future is-a _State_manager
{
}
//移動(dòng)賦值--調(diào)用父類的移動(dòng)賦值
future& operator=(future&& _Right) noexcept
{
_Mybase::operator=(_STD move(_Right));
return (*this);
}
//通過(guò)_State_manager構(gòu)造future
future(const _Mybase& _State, _Nil)
: _Mybase(_State, true)
{
}
//只析構(gòu)future本身,不會(huì)銷毀其父類
~future() noexcept
{ //因?yàn)閒uture沒(méi)有數(shù)據(jù)成員絮重,什么也不做
}
//顯示定義future不可拷貝
future(const future&) = delete;
future& operator=(const future&) = delete;
提取關(guān)聯(lián)的異步狀態(tài)
_Ty get()
{
//移動(dòng)構(gòu)造局部future冤寿,掏空*this
future _Local{_STD move(*this)};
return (_STD move(_Local._Get_value()));
}
通過(guò)std::future::get()提取關(guān)聯(lián)的異步狀態(tài)結(jié)果后,future實(shí)例因?yàn)橐砸苿?dòng)構(gòu)造的方式構(gòu)造局部future對(duì)象(get返回后銷毀)之后青伤,將不再可用(future::valid()返回false)督怜,并且不能通過(guò)future::get()再次提取異步狀態(tài)結(jié)果.
——這并不代表異步狀態(tài)不再存在,只是無(wú)法通過(guò)future::get()一次以上
轉(zhuǎn)換為shared_future
_NODISCARD shared_future<_Ty> share() noexcept
{
return (shared_future<_Ty>(_STD move(*this)));
}
share()實(shí)質(zhì)是通過(guò)future對(duì)象構(gòu)造了shared_future實(shí)例狠角。
shared_future(future<T>&& _Other) noexcept : _Mybase(std::forward<_Mybase>(_Other)) { }
之后future實(shí)例的將不再有效,異步狀態(tài)的訪問(wèn)權(quán)轉(zhuǎn)移到新創(chuàng)建的shared_future.
3. std::shared_future分析
shared_future類的定義
template<class _Ty>
class shared_future
: public _State_manager<_Ty>
{}
shared_future類定義可復(fù)制異步返回對(duì)象号杠,與future一樣繼承自 State_manager,shared_future也沒(méi)有任何數(shù)據(jù)成員,其內(nèi)存布局與父類一模一樣姨蟋,為用戶提供的公共接口函數(shù)實(shí)質(zhì)也是通過(guò)_State_manager的函數(shù)實(shí)現(xiàn).
構(gòu)造屉凯、賦值、析構(gòu)
shared_future() noexcept
{ // construct
}
//支持拷貝
shared_future(const shared_future& _Other) noexcept
: _Mybase(_Other)
{
}
//支持拷貝復(fù)制
shared_future& operator=(const shared_future& _Right) noexcept
{
_Mybase::operator=(_Right);
return (*this);
}
//從future構(gòu)造
shared_future(future<_Ty>&& _Other) noexcept
: _Mybase(_STD forward<_Mybase>(_Other))
{ // construct from rvalue future object
}
//支持移動(dòng)構(gòu)造
shared_future(shared_future&& _Other) noexcept
: _Mybase(_STD move(_Other)) //觸發(fā)_Mybase移動(dòng)構(gòu)造
{
}
//支持移動(dòng)賦值
shared_future& operator=(shared_future&& _Right) noexcept
{
_Mybase::operator=(_STD move(_Right)); ////觸發(fā)_Mybase移動(dòng)賦值
return (*this);
}
~shared_future() noexcept
{ // destroy
}
- 多個(gè)shared_future對(duì)象可以關(guān)聯(lián)同一個(gè)異步狀態(tài)對(duì)象眼溶,故shared_future是可拷貝的
- 不管是構(gòu)造還是賦值悠砚,主要是對(duì)父類_State_manager的拷貝、移動(dòng)堂飞、賦值
- 前面提過(guò)_Get_only_once灌旧,除非在構(gòu)造State_manager時(shí)顯示設(shè)置為true,否則在State_manager實(shí)例中默認(rèn)為false——即異步狀態(tài)對(duì)象可以被多次提取绰筛。在構(gòu)造shared_future時(shí)枢泰,并未顯示的設(shè)置 _Get_only_once為ture,故可以通過(guò)shared_future多次提取關(guān)聯(lián)的異步狀態(tài)铝噩。
提取關(guān)聯(lián)的異步狀態(tài)
_Ty& get() const
{
return (*this->_Get_value());//_State_manager::_Get_value
}
與std::future::get()不同的時(shí)衡蚂,調(diào)用shared_future::get()不會(huì)導(dǎo)致
- shared_future不在有效——因?yàn)椴⑽匆苿?dòng)shared_future
- 多次get()將報(bào)錯(cuò)——因?yàn)開(kāi)Get_only_once為false
4 線程安全性
- 代表異步狀態(tài)結(jié)果的類_Associated_state本身是線程安全的(內(nèi)部通過(guò)互斥鎖和條件變量實(shí)現(xiàn)共享數(shù)據(jù)的安全同步)
- future、shared_future本身非線程安全薄榛,這是因?yàn)槠涓割恄State_manager并非線程安全的讳窟。如果多個(gè)線程同時(shí)操作同一個(gè)future、shared_future敞恋,比如拷貝、析構(gòu)谋右、賦值硬猫,在沒(méi)有額外的同步保護(hù)機(jī)制下,將引發(fā)數(shù)據(jù)競(jìng)爭(zhēng)改执。