容桂網(wǎng)站制作咨詢企業(yè)查詢官網(wǎng)
thread
std::thread
類代表一個(gè)單獨(dú)的執(zhí)行線程。在創(chuàng)建與線程對(duì)象相關(guān)聯(lián)時(shí),線程會(huì)立即開始執(zhí)行(在等待操作系統(tǒng)調(diào)度的延遲之后),從構(gòu)造函數(shù)參數(shù)中提供的頂層函數(shù)開始執(zhí)行。頂層函數(shù)的返回值被忽略,如果它通過拋出異常終止,則會(huì)調(diào)用 std::terminate
。
std::thread
對(duì)象也可以處于不表示任何線程的狀態(tài)(默認(rèn)構(gòu)造、移動(dòng)、分離或加入之后),而且執(zhí)行線程可能不與任何 std::thread
對(duì)象關(guān)聯(lián)(分離之后)。
std::thread
不可復(fù)制構(gòu)造或復(fù)制賦值,但是可以移動(dòng)構(gòu)造和移動(dòng)賦值。
構(gòu)造函數(shù):
- 默認(rèn)構(gòu)造函數(shù)。創(chuàng)建一個(gè)不表示任何線程的新的std::thread對(duì)象。
- 移動(dòng)構(gòu)造函數(shù)。將
other
所表示的線程轉(zhuǎn)移給新的std::thread
對(duì)象。在此調(diào)用后,other
不再表示一個(gè)線程。 - 創(chuàng)建一個(gè)新的
std::thread
對(duì)象并將其與一個(gè)線程關(guān)聯(lián)起來,且新的線程開始執(zhí)行。
析構(gòu)函數(shù):
銷毀線程對(duì)象。 如果 *this 有關(guān)聯(lián)的線程 (joinable() == true),則調(diào)用 std::terminate()。
移動(dòng)構(gòu)造函數(shù):
如果 *this
仍然關(guān)聯(lián)著一個(gè)正在運(yùn)行的線程(即 joinable() == true
),則調(diào)用 std::terminate()
終止程序。否則,將 other
的狀態(tài)賦值給 *this
,并將 other
設(shè)為默認(rèn)構(gòu)造狀態(tài)。
Observers:
joinable:
joinable()
函數(shù)用于檢查 std::thread
對(duì)象是否標(biāo)識(shí)著一個(gè)活動(dòng)的執(zhí)行線程。一個(gè)默認(rèn)構(gòu)造的線程是不可結(jié)合(joinable)的。
get_id:
返回 std::thread::id 的值。
native_handle:
返回實(shí)現(xiàn)定義的底層線程句柄。對(duì)于LInux系統(tǒng)來說,就是返回一個(gè)Linux系統(tǒng)中定義的線程類型值。
hardware_concurrency(static):
返回實(shí)現(xiàn)支持的并發(fā)線程數(shù)。該值應(yīng)僅被視為提示。
Operations:
join:
阻塞當(dāng)前線程,直到由 *this
標(biāo)識(shí)的線程執(zhí)行完成。
detach:
將執(zhí)行線程與線程對(duì)象分開,允許獨(dú)立繼續(xù)執(zhí)行。調(diào)用 detach *this 后不再擁有任何線程。
swap:
交換兩個(gè)線程對(duì)象的底層句柄
Non-member functions:
std::swap:
重載了次類的std::swap算法,其實(shí)現(xiàn)相當(dāng)于調(diào)用成員函數(shù)swap。
管理線程的非成員函數(shù):
std::this_thread::yield();
重新調(diào)度線程的執(zhí)行,讓其他線程運(yùn)行。
std::this_thread:get_id();
返回當(dāng)前線程的id。
std::this_thread::sleep_for();
阻塞當(dāng)前線程的執(zhí)行,至少持續(xù)指定的 sleep_duration。
由于調(diào)度或資源爭(zhēng)用延遲的原因,此函數(shù)可能會(huì)阻塞的時(shí)間超過 sleep_duration。
std::sleep_until();
阻塞當(dāng)前線程的執(zhí)行,直到達(dá)到指定的 sleep_time。
鎖
std::mutex
互斥鎖, 一種獨(dú)占性資源,因此沒有復(fù)制構(gòu)造函數(shù)和復(fù)制運(yùn)算符。線程通過調(diào)用它的成員函數(shù)lock或try_lock才能擁有該互斥量。如果一個(gè)互斥量在任何線程仍然擁有它的情況下被銷毀,或者一個(gè)線程在擁有互斥量時(shí)終止,程序的行為是未定義的。
Member types:
構(gòu)造函數(shù):
只有默認(rèn)構(gòu)造函數(shù)。復(fù)制構(gòu)造函數(shù)被刪除。也沒有移動(dòng)構(gòu)造函數(shù)。
Locking
lock:
對(duì)互斥量加鎖。
try_lock:
嘗試鎖定互斥鎖。立即返回,成功鎖定后返回true,否則返回false。
unlock:
對(duì)互斥鎖解決。
Native handle:
native_handle();
返回底層實(shí)現(xiàn)定義的本地句柄對(duì)象。
std::timed_mutex
timed_mutex 提供了mutex的全部功能,除此之外,還提供了超時(shí)的情況下鎖的是否鎖定的問題。在Linux系統(tǒng)中,它和std::mutex的native_handle()的返回值是一樣的。
它提供了std::mutex的全部的成員函數(shù)。以下是std::mutex沒有的兩個(gè)成員函數(shù)。
Locking:
try_lock_for:
嘗試鎖定互斥。阻塞直到指定的持續(xù)時(shí)間 timeout_duration 已過(超時(shí))或鎖被獲取(擁有互斥),以先到者為準(zhǔn)。成功獲取鎖后返回 true,否則返回 false。
try_lock_until:
嘗試鎖定互斥量。阻塞直到達(dá)到指定的超時(shí)時(shí)間(timeout_time)或成功獲取鎖定(擁有互斥量),以先到者為準(zhǔn)。成功獲取鎖定時(shí)返回 true,否則返回 false。
如果超時(shí)時(shí)間已經(jīng)過去,此函數(shù)的行為類似于 try_lock()。
std::shared_mutex
shared_mutex
具有兩個(gè)級(jí)別的訪問權(quán)限:
- 共享訪問:多個(gè)線程可以共享對(duì)同一個(gè)互斥量的擁有權(quán)。
- 獨(dú)占訪問:只有一個(gè)線程可以擁有互斥量。
在同一個(gè)線程內(nèi),同一時(shí)間只能獲取一個(gè)鎖(共享鎖或獨(dú)占鎖)。它不能被拷貝。
構(gòu)造函數(shù):
默認(rèn)構(gòu)造函數(shù);沒有拷貝構(gòu)造函數(shù)和移動(dòng)構(gòu)造函數(shù)。
沒有賦值運(yùn)算符。
Exclusive locking
lock:
獲得對(duì) shared_mutex 的獨(dú)占所有權(quán)。如果另一個(gè)線程在同一個(gè) shared_mutex 上持有獨(dú)占鎖或共享鎖,調(diào)用鎖定將阻塞執(zhí)行,直到所有此類鎖都被釋放。當(dāng) shared_mutex 以獨(dú)占模式鎖定時(shí),不能同時(shí)持有其他任何類型的鎖。
try_lock:
嘗試鎖定互斥。立即返回。成功鎖定后返回 true,否則返回 false。即使當(dāng)前互斥項(xiàng)未被任何其他線程鎖定,該函數(shù)也允許假失敗并返回 false。如果 try_lock 被一個(gè)已經(jīng)在任何模式(共享或獨(dú)占)下?lián)碛性摶コ忭?xiàng)的線程調(diào)用,其行為將是未定義的。
unlock:
對(duì)此鎖解鎖。
shared locking:
lock_shared:
獲取互斥項(xiàng)的共享所有權(quán)。
try_lock_shared:
嘗試在共享模式下鎖定互斥。立即返回。成功鎖定后返回 true,否則返回 false。即使互斥當(dāng)前未被任何其他線程獨(dú)占鎖定,該函數(shù)也允許錯(cuò)誤地失敗并返回 false。
unlock_shared:
從調(diào)用線程的共享所有權(quán)中釋放互斥。在共享模式下,mutex 必須被當(dāng)前執(zhí)行線程鎖定,否則其行為將是未定義的。
std::shared_timed_mutex
和std::shared_mutex相似,相比于它,沒有native_handle()這樣獲取底層資源的函數(shù),且多了這四個(gè)參數(shù):
try_lock_for:
嘗試獲取互斥量的鎖。阻塞直到指定的持續(xù)時(shí)間 timeout_duration
經(jīng)過(超時(shí))或者成功獲取鎖(擁有互斥量),以先到者為準(zhǔn)。如果成功獲取鎖,則返回 true,否則返回 false。由于調(diào)度或資源爭(zhēng)用延遲,此函數(shù)可能會(huì)阻塞超過 timeout_duration
的時(shí)間。與 try_lock()
類似,即使在 timeout_duration
的某個(gè)時(shí)間點(diǎn)上互斥量沒有被其他線程鎖定,此函數(shù)也可以出現(xiàn)虛假失敗并返回 false。
try_lock_until:
嘗試獲取互斥量的鎖。阻塞直到達(dá)到指定的超時(shí)時(shí)間 timeout_time
(到達(dá)超時(shí))或成功獲取鎖(擁有互斥量),以先到者為準(zhǔn)。如果成功獲取鎖,則返回 true,否則返回 false。如果超時(shí)時(shí)間 timeout_time
已經(jīng)過去,則此函數(shù)的行為類似于 try_lock()
。與 try_lock()
類似,即使在超時(shí)時(shí)間之前互斥量沒有被其他線程鎖定,該函數(shù)也可以出現(xiàn)虛假失敗并返回 false。
try_lock_shared_for:
與try_lock_for類似,只是獲取的是共享鎖。
try_lock_shared_until:
與try_lock_until類似,只是獲取的是共享鎖。
鎖管理
std::lock_guard
lock_guard 類是一個(gè)互斥包裝器, 當(dāng)創(chuàng)建 lock_guard 對(duì)象時(shí),它會(huì)嘗試獲取所給互斥的所有權(quán)。當(dāng)控制權(quán)離開創(chuàng)建 lock_guard 對(duì)象的作用域時(shí),lock_guard 會(huì)被析構(gòu),mutex 也會(huì)被釋放。lock_guard類不可被拷貝,沒有賦值運(yùn)算符。
它的模板參數(shù)必須符合BasicLockable要求。
構(gòu)造函數(shù):
- 接受一個(gè)鎖參數(shù),然后立刻調(diào)用其lock()成員函數(shù)。
- 獲取 mutex m 的所有權(quán),但不試圖鎖定它。如果當(dāng)前線程未持有 m 上的非共享鎖,則該行為未定義。
析構(gòu)函數(shù):
調(diào)用擁有的鎖的unlock()。
std::unique_lock
類unique_lock
是一個(gè)通用的互斥量所有權(quán)包裝器,允許延遲鎖定、限時(shí)嘗試鎖定、遞歸鎖定、鎖的所有權(quán)轉(zhuǎn)移以及與條件變量一起使用。類unique_lock
是可移動(dòng)的,但不可復(fù)制。
構(gòu)造函數(shù):
- 默認(rèn)構(gòu)造函數(shù),構(gòu)造一個(gè)沒有關(guān)聯(lián)互斥量的對(duì)象。
- 移動(dòng)構(gòu)造函數(shù),用其他對(duì)象的內(nèi)容初始化
unique_lock
對(duì)象,同時(shí)將其他對(duì)象置為沒有關(guān)聯(lián)互斥量。 - 使用互斥量
m
構(gòu)造一個(gè)關(guān)聯(lián)的unique_lock
對(duì)象,然后可以通過選擇是否傳參以及傳遞什么參數(shù),使互斥量被鎖定、不鎖定、調(diào)用try_lock()鎖定、認(rèn)為互斥量是非共享鎖定狀態(tài)的、調(diào)用try_lock_for或調(diào)用try_lock_until的。
析構(gòu)函數(shù):
如果 *this 有關(guān)聯(lián)的互鎖體,并且已獲得其所有權(quán),則互鎖體被解鎖。
移動(dòng)賦值操作符:
使用移動(dòng)語義將內(nèi)容替換為其他內(nèi)容。如果在調(diào)用 *this 之前已關(guān)聯(lián)了一個(gè)互斥項(xiàng)并獲得了它的所有權(quán),則互斥項(xiàng)將被解鎖。
Locking:
lock:
鎖定擁有的互斥。實(shí)際上是調(diào)用擁有互斥的lock成員函數(shù)。
try_lock:
嘗試在不阻塞的情況下鎖定(即獲取)相關(guān)的互斥。實(shí)際上是調(diào)用 mutex()->try_lock()。
try_lock_for:
實(shí)際上調(diào)用了 mutex()->try_lock_for(timeout_duration)。
try_lock_until:
實(shí)際上調(diào)用了 mutex()->try_lock_until(timeout_time)。
unlock:
解鎖。實(shí)際上調(diào)用了mutex()->unlock();
Modifiers:
swap;
交換鎖對(duì)象的內(nèi)部狀態(tài)。
release():
中斷相關(guān)互斥(如果有)與 *this 的關(guān)聯(lián)。不會(huì)解鎖任何鎖。
Observers:
mutex();
返回指向相關(guān)靜態(tài)代理的指針,如果沒有相關(guān)靜態(tài)代理,則返回空指針。
owns_lock();
檢查 *this 是否擁有鎖定的互斥。
std::shared_lock
類shared_lock
是一個(gè)通用的共享互斥量所有權(quán)包裝器,允許延遲鎖定、定時(shí)鎖定和鎖的所有權(quán)轉(zhuǎn)移。通過對(duì)shared_lock
進(jìn)行鎖定,將以共享模式鎖定關(guān)聯(lián)的共享互斥量. shared_lock
類是可移動(dòng)的,但不可復(fù)制。
構(gòu)造函數(shù):
- 默認(rèn)構(gòu)造函數(shù),構(gòu)造一個(gè)沒有關(guān)聯(lián)互斥量的對(duì)象。
- 移動(dòng)構(gòu)造函數(shù),用其他對(duì)象的內(nèi)容初始化
shared_lock
對(duì)象,同時(shí)將其他對(duì)象置為沒有關(guān)聯(lián)互斥量。 - 使用互斥量
m
構(gòu)造一個(gè)關(guān)聯(lián)的shared_lock
對(duì)象,然后可以通過選擇是否傳參以及傳遞什么參數(shù),使互斥量以共享模式被鎖定、不鎖定、調(diào)用try_lock_shared()鎖定、認(rèn)為互斥量是共享鎖定狀態(tài)的、調(diào)用try_lock_shared_for或調(diào)用try_lock_shared_until的。
析構(gòu)函數(shù):
如果 *this 有關(guān)聯(lián)的互鎖體,并且已獲得其所有權(quán),則通過調(diào)用 unlock_shared() 來解鎖互鎖體。
賦值運(yùn)算符:
使用移動(dòng)語義將內(nèi)容替換為其他內(nèi)容。如果在調(diào)用 *this 之前已關(guān)聯(lián)了一個(gè)互斥項(xiàng)并獲得了它的所有權(quán),則會(huì)通過調(diào)用 unlock_shared() 來解鎖互斥體。
Locking:
lock:
以共享模式鎖定相關(guān)的互斥。實(shí)際上是調(diào)用擁有互斥的lock_shared成員函數(shù)。
try_lock:
嘗試在不阻塞的情況下以共享模式鎖定相關(guān)的互斥。實(shí)際上是調(diào)用 mutex()->try_lock_shared()。
try_lock_for:
實(shí)際上調(diào)用了 mutex()->try_lock_shared_for(timeout_duration)。
try_lock_until:
實(shí)際上調(diào)用了 mutex()->try_lock_shared_until(timeout_time)。
unlock:
解鎖。實(shí)際上調(diào)用了mutex()->unlock_shared();
Modifiers:
swap;
交換鎖對(duì)象的內(nèi)部狀態(tài)。
release():
中斷相關(guān)互斥(如果有)與 *this 的關(guān)聯(lián)。不會(huì)解鎖任何鎖。
Observers:
mutex();
返回指向相關(guān)靜態(tài)代理的指針,如果沒有相關(guān)靜態(tài)代理,則返回空指針。
owns_lock();
檢查 *this 是否擁有共享互斥量的共享所有權(quán)。
std::scoped_lock
類scoped_lock
是一個(gè)互斥量包裝器, 用于在作用域塊的持續(xù)時(shí)間內(nèi)擁有零個(gè)或多個(gè)互斥量。如果給定了多個(gè)互斥量,則會(huì)使用避免死鎖的算法,類似于std::lock
的行為。scoped_lock
類是不可復(fù)制的。
構(gòu)造函數(shù):
- 獲取給定互斥量的所有權(quán),即調(diào)用對(duì)應(yīng)的lock成員函數(shù)。
- 在不嘗試鎖定任何互斥量的情況下獲取互斥量
m...
的所有權(quán)。除非當(dāng)前線程對(duì)m...
中的每個(gè)對(duì)象都持有非共享鎖,否則行為是未定義的。
析構(gòu)函數(shù):
釋放所有互斥的所有權(quán),及調(diào)用每個(gè)互斥體的unlock()成員函數(shù)。
賦值運(yùn)算符已經(jīng)被刪除。
Call once
call_once:
once_flag:
Condition variables
條件變量的喚醒丟失與虛假喚醒問題。
std::condition_variable
condition_variable 類是與 std::mutex 一起使用的同步原語,用于阻塞一個(gè)或多個(gè)線程,直到另一個(gè)線程修改了共享變量(條件)并通知 condition_variable。std::condition_variable僅適用于std::unique_lockstd::mutex,這樣可以在某些平臺(tái)上實(shí)現(xiàn)最高效率。
它不可被移動(dòng)或復(fù)制。
構(gòu)造函數(shù):
默認(rèn)構(gòu)造函數(shù),構(gòu)造一個(gè)std::condition_variable對(duì)象。
析構(gòu)函數(shù):
銷毀 std::condition_variable 類型的對(duì)象。只有在所有線程都已被通知的情況下才能安全地調(diào)用析構(gòu)函數(shù)。
Notification:
notify_one():
如果有線程正在等待 *this,調(diào)用 notify_one 會(huì)解除其中一個(gè)等待線程的阻塞。
notify_all():
解除當(dāng)前等待 *this 的所有線程的阻塞。
Waiting:
wait:
wait
函數(shù)會(huì)導(dǎo)致當(dāng)前線程阻塞,直到條件變量被通知或出現(xiàn)虛假喚醒。它有兩個(gè)重載。
- 只有參數(shù)鎖:原子性地解鎖
lock
,阻塞當(dāng)前執(zhí)行的線程,并將其添加到等待 *this 的線程列表中。它被喚醒而解除阻塞時(shí),都會(huì)重新獲取互斥鎖并退出 wait 函數(shù)。 - 有參數(shù)鎖和謂詞:等價(jià)于如下代碼:
while (!stop_waiting()) { // stop_waiting函數(shù)是謂詞wait(lock);
}
這個(gè)重載函數(shù)可以避免虛假喚醒的問題。
這里的鎖必須是std::unique_lockstd::mutex
wait_for: wait_until:
前者是最多阻塞的相對(duì)超時(shí)時(shí)間,后者是最多阻塞到某個(gè)時(shí)間點(diǎn)。它們其余部分和wait一致。
Native handle:
native_handle():訪問 *this 的本地句柄。
std::condition_variable_any
class condition_variable_any 是 std::condition_variable 的一個(gè)更通用的版本。而 std::condition_variable 只能與 std::unique_lockstd::mutex 一起使用,condition_variable_any 可以操作任何滿足 BasicLockable 要求的鎖。
class std::condition_variable_any 是一個(gè) StandardLayoutType。它不可被移動(dòng)或復(fù)制。
如果鎖是 std::unique_lockstd::mutex,則 std::condition_variable 可能提供更好的性能。
下面列出些std::condition_variable沒有的功能:
wait;wait_for; wait_until:
都多了第三個(gè)重載,多了一個(gè)stoken變量:多了一個(gè) std::stop_token 對(duì)象,用于支持取消等待操作。當(dāng)外部發(fā)出取消請(qǐng)求時(shí),可以通過該對(duì)象檢查并中止等待。
Latches and Barriers
Futures
Futures 功能是并發(fā)編程機(jī)制,旨在簡(jiǎn)化多線程編程和異步操作的處理。Futures 提供了一種在一個(gè)線程中計(jì)算值或執(zhí)行任務(wù),并在另一個(gè)線程中獲取結(jié)果的方法。
它的核心組件時(shí)std::future
和 std::promise
。std::future
對(duì)象與 std::promise
對(duì)象之間共享一個(gè)狀態(tài)。通過 std::promise
對(duì)象設(shè)置的值可以通過與其關(guān)聯(lián)的 std::future
對(duì)象來獲取。這樣就可以使一個(gè)線程使用 std::promise
對(duì)象來設(shè)置異步操作的結(jié)果,而另一個(gè)線程使用對(duì)應(yīng)的 std::future
對(duì)象來獲取結(jié)果。
std::futuer
std::future
提供了一種訪問異步操作結(jié)果的機(jī)制, 通過std::async、std::packaged_task或std::promise創(chuàng)建的異步操作可以向該異步操作的創(chuàng)建者提供一個(gè)std::future對(duì)象。異步操作的創(chuàng)建者可以使用各種方法來查詢、等待或從std::future
中提取值。
構(gòu)造函數(shù):
- 默認(rèn)構(gòu)造函數(shù),創(chuàng)建一個(gè)沒有共享狀態(tài)的 std::future 對(duì)象。
- 移動(dòng)構(gòu)造函數(shù),構(gòu)造后,被移動(dòng)的對(duì)象沒有共享狀態(tài)
- 拷貝構(gòu)造函數(shù)被刪除。
析構(gòu)函數(shù):
釋放任何共享狀態(tài)不會(huì)阻塞等待共享狀態(tài)變?yōu)榫途w,除非以下所有條件都成立時(shí)可能會(huì)阻塞:(一定會(huì)阻塞嗎?????)
- 共享狀態(tài)是通過調(diào)用
std::async
創(chuàng)建的。 - 共享狀態(tài)尚未就緒。
- 當(dāng)前對(duì)象是對(duì)共享狀態(tài)的最后一個(gè)引用。
這些操作只有在任務(wù)的啟動(dòng)策略為 std::launch::async
時(shí)才會(huì)阻塞
只有移動(dòng)賦值運(yùn)算符,沒有拷貝賦值運(yùn)算符。移動(dòng)后,被移動(dòng)的對(duì)象沒有共享狀態(tài)。
share():
將 *this 的共享狀態(tài)(如果有的話)轉(zhuǎn)移給一個(gè) std::shared_future
對(duì)象。在調(diào)用 share
后,valid() == false
。
Getting the result:
get():
阻塞當(dāng)前線程,直到future準(zhǔn)備妥當(dāng)并返回該值,或者拋出異步運(yùn)行的函數(shù)的異常或被設(shè)置的異常. 在調(diào)用此成員函數(shù)后,共享狀態(tài)會(huì)被釋放, valid()
為 false。如果在調(diào)用此函數(shù)之前 valid()
為 false,則行為是未定義的。
State:
valid:
檢查 future
是否引用共享狀態(tài)。
wait:
阻塞直到結(jié)果變?yōu)榭捎谩?/p>
wait_for:
等待結(jié)果變?yōu)榭捎?。阻塞直到指定?timeout_duration
經(jīng)過或結(jié)果可用,以先到者為準(zhǔn)。返回值標(biāo)識(shí)結(jié)果的狀態(tài)。如果 future
是通過使用lazy evaluation的方式調(diào)用 std::async
的結(jié)果,該函數(shù)會(huì)立即返回而不等待。
wait_until:
wait_until
函數(shù)等待結(jié)果變?yōu)榭捎谩K鼤?huì)阻塞直到達(dá)到指定的 timeout_time
或結(jié)果可用,以先到者為準(zhǔn)。返回值指示 wait_until
返回的原因。如果 future
是通過使用lazy evaluation的方式調(diào)用 std::async
的結(jié)果,該函數(shù)會(huì)立即返回而不等待。
std::shared_future
std::shared_future類似于 std::future
,但允許多個(gè)線程等待相同的共享狀態(tài)。std::shared_future
是既可移動(dòng),也可復(fù)制的,多個(gè)共享的 std::shared_future
對(duì)象可以引用相同的共享狀態(tài)。通過各自的 std::shared_future
對(duì)象,多個(gè)線程可以安全地訪問相同的共享狀態(tài)。
構(gòu)造函數(shù):
- 默認(rèn)構(gòu)造函數(shù)。構(gòu)造一個(gè)空的shared_future, 不引用共享狀態(tài)。
- 拷貝構(gòu)造函數(shù),構(gòu)造一個(gè)引用與other相同共享狀態(tài)(如果有的話)的shared_future.
- 移動(dòng)構(gòu)造函數(shù),將
other
持有的共享狀態(tài)轉(zhuǎn)移給*this
。構(gòu)造后,other.valid() == false
,且this->valid()
的返回值與在構(gòu)造之前other.valid()
的返回值相同。
賦值運(yùn)算符:
- 拷貝賦值運(yùn)算符:1. 釋放任何共享狀態(tài),并將
other
的內(nèi)容賦值給*this
。賦值后,this->valid() == other.valid()
。 - 移動(dòng)賦值運(yùn)算符:1. 釋放任何共享狀態(tài),并將
other
的內(nèi)容移動(dòng)賦值給*this
。賦值后,other.valid() == false
,并且this->valid()
的返回值與賦值之前的other.valid()
的返回值相同。
Getting the result:
get:
get
成員函數(shù)會(huì)等待直到 shared_future
有一個(gè)有效的結(jié)果,并且(根據(jù)使用的模板)獲取它。它實(shí)際上會(huì)調(diào)用 wait()
來等待結(jié)果。與 std::future
不同,當(dāng)調(diào)用 get()
時(shí),std::shared_future
的共享狀態(tài)不會(huì)無效。
State:
valid();
檢查 shared_future
是否引用共享狀態(tài)。
wait():
調(diào)用后 valid() == true。如果在調(diào)用此函數(shù)之前 valid() == false,則行為未定義。
wait_for();
等待結(jié)果可用。阻塞直到指定的 timeout_duration 已過或結(jié)果可用,以先到者為準(zhǔn)。返回值標(biāo)識(shí)結(jié)果的狀態(tài)。如果 future 是調(diào)用 std::async 并使用了懶評(píng)估的結(jié)果,則此函數(shù)無需等待,立即返回。
wait_until();
wait_until 等待結(jié)果可用。它會(huì)阻塞,直到達(dá)到指定的 timeout_time 或結(jié)果可用為止,以先到者為準(zhǔn)。返回值說明 wait_until 返回的原因。如果 future 是調(diào)用 async 時(shí)使用了懶評(píng)估的結(jié)果,則此函數(shù)會(huì)立即返回而無需等待。
std::async()
函數(shù)模板 std::async
異步地運(yùn)行函數(shù) f
(可能在一個(gè)獨(dú)立的線程中,該線程可能是線程池的一部分),并返回一個(gè) std::future
,最終將保存該函數(shù)調(diào)用的結(jié)果。它可以根據(jù)系統(tǒng)情況自動(dòng)選擇是獨(dú)立啟動(dòng)一個(gè)線程運(yùn)行,還是在對(duì)應(yīng)的future調(diào)用get時(shí)運(yùn)行;也可以由調(diào)用者指定任務(wù)調(diào)用策略。
任務(wù)調(diào)用策略:
- std::launch::async; 開啟一個(gè)獨(dú)立線程執(zhí)行任務(wù)
- std::launch::deferred; 使用延遲批評(píng)估。
請(qǐng)注意,除了調(diào)用 std::async 之外,通過其他方式獲得的 std::futures 的析構(gòu)函數(shù)永遠(yuǎn)不會(huì)阻塞。
構(gòu)造函數(shù):
- 不加策略的構(gòu)造函數(shù)
- 加策略的構(gòu)造函數(shù)
std::package_task<>
類模板 std::packaged_task
可以封裝任何可調(diào)用目標(biāo),以便可以異步調(diào)用它。它的返回值或拋出的異常被存儲(chǔ)在一個(gè)共享狀態(tài)中,可以通過 std::future
對(duì)象訪問該狀態(tài)。它不可被復(fù)制。
默認(rèn)構(gòu)造函數(shù):
- 構(gòu)造一個(gè)沒有任務(wù)和共享狀態(tài)的
std::packaged_task
對(duì)象。 - 構(gòu)造一個(gè)具有共享狀態(tài)和任務(wù)副本的
std::packaged_task
對(duì)象,使用std::forward<F>(f)
進(jìn)行初始化。 - 復(fù)制構(gòu)造函數(shù)被刪除,
std::packaged_task
是只可移動(dòng)的 - 移動(dòng)構(gòu)造函數(shù),構(gòu)造一個(gè)具有共享狀態(tài)和任務(wù)的
std::packaged_task
,該狀態(tài)和任務(wù)原先由rhs
擁有,將rhs
置于無共享狀態(tài)和已移動(dòng)的任務(wù)狀態(tài)。
析構(gòu)函數(shù):
放棄共享狀態(tài)并銷毀存儲(chǔ)的任務(wù)對(duì)象。如果共享狀態(tài)在準(zhǔn)備就緒之前被放棄,則會(huì)存儲(chǔ)一個(gè) std::future_error 異常,錯(cuò)誤代碼為 std::future_errc::broken_promise。
復(fù)制運(yùn)算符:
只有移動(dòng)賦值運(yùn)算符。移動(dòng)賦值運(yùn)算符:釋放共享狀態(tài)(如果有),銷毀之前持有的任務(wù),并將共享狀態(tài)和 rhs 擁有的任務(wù)移入 *this。
valid();
檢查是否有一個(gè)共享狀態(tài),即是否包含一個(gè)有效的任務(wù)。
swap():
將"*this"和"other"的共享狀態(tài)和存儲(chǔ)的任務(wù)進(jìn)行交換。
Getting the result:
get_future:
用于獲取一個(gè) std::future
對(duì)象,該對(duì)象與當(dāng)前 std::packaged_task
共享相同的共享狀態(tài)。get_future()
函數(shù)只能調(diào)用一次.
Execution:
operator():
執(zhí)行存儲(chǔ)中的任務(wù)。任務(wù)的返回值或拋出的任何異常都會(huì)存儲(chǔ)在共享狀態(tài)中。
make_ready_at_thread_exit:
共享狀態(tài)只有在當(dāng)前線程退出并且所有具有線程局部存儲(chǔ)期的對(duì)象被銷毀后,才會(huì)準(zhǔn)備就緒。
reset():
重置狀態(tài),放棄之前的執(zhí)行結(jié)果。構(gòu)建新的共享狀態(tài)。
std::promise<>
類模板 std::promise
提供了一種存儲(chǔ)值或異常的機(jī)制,這些值或異常可以通過由 std::promise
對(duì)象創(chuàng)建的 std::future
對(duì)象在異步方式下獲取。std::promise
對(duì)象只能使用一次,因此不可被復(fù)制。
每個(gè) promise 關(guān)聯(lián)一個(gè)共享狀態(tài), 它可以對(duì)共享狀態(tài)執(zhí)行三種操作:
- 準(zhǔn)備就緒:
promise 將結(jié)果或異常存儲(chǔ)在共享狀態(tài)中。標(biāo)記狀態(tài)為就緒,并解除任何等待與共享狀態(tài)相關(guān)聯(lián)的 future 的線程的阻塞。 - 釋放:
promise 放棄對(duì)共享狀態(tài)的引用。如果這是最后一個(gè)對(duì)共享狀態(tài)的引用,那么共享狀態(tài)將被銷毀。 - 放棄:
promise 將類型為 std::future_error,錯(cuò)誤代碼為 std::future_errc::broken_promise 的異常存儲(chǔ)在共享狀態(tài)中,使共享狀態(tài)變?yōu)榫途w狀態(tài),然后釋放它。
構(gòu)造函數(shù):(拷貝構(gòu)造函數(shù)被刪除)
- 默認(rèn)構(gòu)造函數(shù)。使用空的共享狀態(tài)構(gòu)造promise。
- 移動(dòng)構(gòu)造函數(shù)。使用移動(dòng)語義構(gòu)造 promise,使用其他 promise 的共享狀態(tài)。構(gòu)造完成后,其他 promise 不再具有共享狀態(tài)。
析構(gòu)函數(shù):
- 如果共享狀態(tài)已就緒,則釋放共享狀態(tài)。
- 如果共享狀態(tài)未就緒,則存儲(chǔ)一個(gè) std::future_error 類型的異常對(duì)象(錯(cuò)誤條件為 std::future_errc::broken_promise),使共享狀態(tài)就緒并釋放它。
賦值運(yùn)算符:(沒有拷貝運(yùn)算符)
移動(dòng)賦值操作符。首先,放棄共享狀態(tài),然后通過執(zhí)行 std::promise(std::move(other)).swap(*this) 賦值給 other 的共享狀態(tài)。
Getting the result:
get_future:
返回與 *this 相同共享狀態(tài)相關(guān)聯(lián)的std::future。
set_value; set_value_at_thread_exit;
原子式地將值存儲(chǔ)到共享狀態(tài)中,并使?fàn)顟B(tài)就緒。如果沒有共享狀態(tài)或共享狀態(tài)已存儲(chǔ)值或異常,則會(huì)拋出異常。
前者是立即讓共享狀態(tài)就緒,后者是等當(dāng)前線程退出時(shí),所有具有線程本地存儲(chǔ)期限的變量都已銷毀,狀態(tài)才會(huì)就緒。
set_exception; set_exception_at_thread_exit;
除了存儲(chǔ)的是異常,其余和set_value; set_value_at_thread_exit;完全一致。
set_value: 保存值
set_exception: 保存異常