<condition_variable>頭文件提供了條件變量的定義。其作為基本同步機(jī)制,允許被阻塞的線程在某些條件達(dá)成或超時(shí)時(shí),解除阻塞繼續(xù)執(zhí)行。
namespace std
{
enum class cv_status { timeout, no_timeout };
class condition_variable;
class condition_variable_any;
}
std::condition_variable允許阻塞一個(gè)線程,直到條件達(dá)成。
std::condition_variable實(shí)例不支持CopyAssignable(拷貝賦值), CopyConstructible(拷貝構(gòu)造), MoveAssignable(移動(dòng)賦值)和 MoveConstructible(移動(dòng)構(gòu)造)。
class condition_variable
{
public:
condition_variable();
~condition_variable();
condition_variable(condition_variable const& ) = delete;
condition_variable& operator=(condition_variable const& ) = delete;
void notify_one() noexcept;
void notify_all() noexcept;
void wait(std::unique_lock<std::mutex>& lock);
template <typename Predicate>
void wait(std::unique_lock<std::mutex>& lock,Predicate pred);
template <typename Clock, typename Duration>
cv_status wait_until(
std::unique_lock<std::mutex>& lock,
const std::chrono::time_point<Clock, Duration>& absolute_time);
template <typename Clock, typename Duration, typename Predicate>
bool wait_until(
std::unique_lock<std::mutex>& lock,
const std::chrono::time_point<Clock, Duration>& absolute_time,
Predicate pred);
template <typename Rep, typename Period>
cv_status wait_for(
std::unique_lock<std::mutex>& lock,
const std::chrono::duration<Rep, Period>& relative_time);
template <typename Rep, typename Period, typename Predicate>
bool wait_for(
std::unique_lock<std::mutex>& lock,
const std::chrono::duration<Rep, Period>& relative_time,
Predicate pred);
};
void notify_all_at_thread_exit(condition_variable&,unique_lock<mutex>);
構(gòu)造一個(gè)std::condition_variable對(duì)象。
聲明
condition_variable();
效果
構(gòu)造一個(gè)新的std::condition_variable實(shí)例。
拋出
當(dāng)條件變量無法夠早的時(shí)候,將會(huì)拋出一個(gè)std::system_error異常。
銷毀一個(gè)std::condition_variable對(duì)象。
聲明
~condition_variable();
先決條件
之前沒有使用*this總的wait(),wait_for()或wait_until()阻塞過線程。
效果
銷毀*this。
拋出
無
喚醒一個(gè)等待當(dāng)前std::condition_variable實(shí)例的線程。
聲明
void notify_one() noexcept;
效果
喚醒一個(gè)等待*this的線程。如果沒有線程在等待,那么調(diào)用沒有任何效果。
拋出
當(dāng)效果沒有達(dá)成,就會(huì)拋出std::system_error異常。
同步
std::condition_variable實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
喚醒所有等待當(dāng)前std::condition_variable實(shí)例的線程。
聲明
void notify_all() noexcept;
效果
喚醒所有等待*this的線程。如果沒有線程在等待,那么調(diào)用沒有任何效果。
拋出
當(dāng)效果沒有達(dá)成,就會(huì)拋出std::system_error異常
同步
std::condition_variable實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
通過std::condition_variable的notify_one()、notify_all()或偽喚醒結(jié)束等待。
等待
void wait(std::unique_lock<std::mutex>& lock);
先決條件
當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。
效果
自動(dòng)解鎖lock對(duì)象,對(duì)于線程等待線程,當(dāng)其他線程調(diào)用notify_one()或notify_all()時(shí)被喚醒,亦或該線程處于偽喚醒狀態(tài)。在wait()返回前,lock對(duì)象將會(huì)再次上鎖。
拋出
當(dāng)效果沒有達(dá)成的時(shí)候,將會(huì)拋出std::system_error異常。當(dāng)lock對(duì)象在調(diào)用wait()階段被解鎖,那么當(dāng)wait()退出的時(shí)候lock會(huì)再次上鎖,即使函數(shù)是通過異常的方式退出。
NOTE:偽喚醒意味著一個(gè)線程調(diào)用wait()后,在沒有其他線程調(diào)用notify_one()或notify_all()時(shí),還處以蘇醒狀態(tài)。因此,建議對(duì)wait()進(jìn)行重載,在可能的情況下使用一個(gè)謂詞。否則,建議wait()使用循環(huán)檢查與條件變量相關(guān)的謂詞。
同步
std::condition_variable實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
等待std::condition_variable上的notify_one()或notify_all()被調(diào)用,或謂詞為true的情況,來喚醒線程。
聲明
template<typename Predicate>
void wait(std::unique_lock<std::mutex>& lock,Predicate pred);
先決條件
pred()謂詞必須是合法的,并且需要返回一個(gè)值,這個(gè)值可以和bool互相轉(zhuǎn)化。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。
效果
正如
while(!pred())
{
wait(lock);
}
拋出
pred中可以拋出任意異常,或者當(dāng)效果沒有達(dá)到的時(shí)候,拋出std::system_error異常。
NOTE:潛在的偽喚醒意味著不會(huì)指定pred調(diào)用的次數(shù)。通過lock進(jìn)行上鎖,pred經(jīng)常會(huì)被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個(gè)值,在(bool)pred()評(píng)估后,返回true。
同步
std::condition_variable實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
std::condition_variable在調(diào)用notify_one()、調(diào)用notify_all()、超時(shí)或線程偽喚醒時(shí),結(jié)束等待。
聲明
template<typename Rep,typename Period>
cv_status wait_for(
std::unique_lock<std::mutex>& lock,
std::chrono::duration<Rep,Period> const& relative_time);
先決條件
當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。
效果
當(dāng)其他線程調(diào)用notify_one()或notify_all()函數(shù)時(shí),或超出了relative_time的時(shí)間,亦或是線程被偽喚醒,則將lock對(duì)象自動(dòng)解鎖,并將阻塞線程喚醒。當(dāng)wait_for()調(diào)用返回前,lock對(duì)象會(huì)再次上鎖。
返回
線程被notify_one()、notify_all()或偽喚醒喚醒時(shí),會(huì)返回std::cv_status::no_timeout;反之,則返回std::cv_status::timeout。
拋出
當(dāng)效果沒有達(dá)成的時(shí)候,會(huì)拋出std::system_error異常。當(dāng)lock對(duì)象在調(diào)用wait_for()函數(shù)前解鎖,那么lock對(duì)象會(huì)在wait_for()退出前再次上鎖,即使函數(shù)是以異常的方式退出。
NOTE:偽喚醒意味著,一個(gè)線程在調(diào)用wait_for()的時(shí)候,即使沒有其他線程調(diào)用notify_one()和notify_all()函數(shù),也處于蘇醒狀態(tài)。因此,這里建議重載wait_for()函數(shù),重載函數(shù)可以使用謂詞。要不,則建議wait_for()使用循環(huán)的方式對(duì)與謂詞相關(guān)的條件變量進(jìn)行檢查。在這樣做的時(shí)候還需要小心,以確保超時(shí)部分依舊有效;wait_until()可能適合更多的情況。這樣的話,線程阻塞的時(shí)間就要比指定的時(shí)間長(zhǎng)了。在有這樣可能性的地方,流逝的時(shí)間是由穩(wěn)定時(shí)鐘決定。
同步
std::condition_variable實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
std::condition_variable在調(diào)用notify_one()、調(diào)用notify_all()、超時(shí)或線程偽喚醒時(shí),結(jié)束等待。
聲明
template<typename Rep,typename Period,typename Predicate>
bool wait_for(
std::unique_lock<std::mutex>& lock,
std::chrono::duration<Rep,Period> const& relative_time,
Predicate pred);
先決條件
pred()謂詞必須是合法的,并且需要返回一個(gè)值,這個(gè)值可以和bool互相轉(zhuǎn)化。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。
效果
等價(jià)于
internal_clock::time_point end=internal_clock::now()+relative_time;
while(!pred())
{
std::chrono::duration<Rep,Period> remaining_time=
end-internal_clock::now();
if(wait_for(lock,remaining_time)==std::cv_status::timeout)
return pred();
}
return true;
返回
當(dāng)pred()為true,則返回true;當(dāng)超過relative_time并且pred()返回false時(shí),返回false。
NOTE:潛在的偽喚醒意味著不會(huì)指定pred調(diào)用的次數(shù)。通過lock進(jìn)行上鎖,pred經(jīng)常會(huì)被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個(gè)值,在(bool)pred()評(píng)估后返回true,或在指定時(shí)間relative_time內(nèi)完成。線程阻塞的時(shí)間就要比指定的時(shí)間長(zhǎng)了。在有這樣可能性的地方,流逝的時(shí)間是由穩(wěn)定時(shí)鐘決定。
拋出
當(dāng)效果沒有達(dá)成時(shí),會(huì)拋出std::system_error異常或者由pred拋出任意異常。
同步
std::condition_variable實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
std::condition_variable在調(diào)用notify_one()、調(diào)用notify_all()、指定時(shí)間內(nèi)達(dá)成條件或線程偽喚醒時(shí),結(jié)束等待。
聲明
template<typename Clock,typename Duration>
cv_status wait_until(
std::unique_lock<std::mutex>& lock,
std::chrono::time_point<Clock,Duration> const& absolute_time);
先決條件
當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。
效果
當(dāng)其他線程調(diào)用notify_one()或notify_all()函數(shù),或Clock::now()返回一個(gè)大于或等于absolute_time的時(shí)間,亦或線程偽喚醒,lock都將自動(dòng)解鎖,并且喚醒阻塞的線程。在wait_until()返回之前l(fā)ock對(duì)象會(huì)再次上鎖。
返回
線程被notify_one()、notify_all()或偽喚醒喚醒時(shí),會(huì)返回std::cv_status::no_timeout;反之,則返回std::cv_status::timeout。
拋出
當(dāng)效果沒有達(dá)成的時(shí)候,會(huì)拋出std::system_error異常。當(dāng)lock對(duì)象在調(diào)用wait_for()函數(shù)前解鎖,那么lock對(duì)象會(huì)在wait_for()退出前再次上鎖,即使函數(shù)是以異常的方式退出。
NOTE:偽喚醒意味著一個(gè)線程調(diào)用wait()后,在沒有其他線程調(diào)用notify_one()或notify_all()時(shí),還處以蘇醒狀態(tài)。因此,這里建議重載wait_until()函數(shù),重載函數(shù)可以使用謂詞。要不,則建議wait_until()使用循環(huán)的方式對(duì)與謂詞相關(guān)的條件變量進(jìn)行檢查。這里不保證線程會(huì)被阻塞多長(zhǎng)時(shí)間,只有當(dāng)函數(shù)返回false后(Clock::now()的返回值大于或等于absolute_time),線程才能解除阻塞。
同步
std::condition_variable實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
std::condition_variable在調(diào)用notify_one()、調(diào)用notify_all()、謂詞返回true或指定時(shí)間內(nèi)達(dá)到條件,結(jié)束等待。
聲明
template<typename Clock,typename Duration,typename Predicate>
bool wait_until(
std::unique_lock<std::mutex>& lock,
std::chrono::time_point<Clock,Duration> const& absolute_time,
Predicate pred);
先決條件
pred()必須是合法的,并且其返回值能轉(zhuǎn)換為bool值。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。
效果
等價(jià)于
while(!pred())
{
if(wait_until(lock,absolute_time)==std::cv_status::timeout)
return pred();
}
return true;
返回
當(dāng)調(diào)用pred()返回true時(shí),返回true;當(dāng)Clock::now()的時(shí)間大于或等于指定的時(shí)間absolute_time,并且pred()返回false時(shí),返回false。
NOTE:潛在的偽喚醒意味著不會(huì)指定pred調(diào)用的次數(shù)。通過lock進(jìn)行上鎖,pred經(jīng)常會(huì)被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個(gè)值,在(bool)pred()評(píng)估后返回true,或Clock::now()返回的時(shí)間大于或等于absolute_time。這里不保證調(diào)用線程將被阻塞的時(shí)長(zhǎng),只有當(dāng)函數(shù)返回false后(Clock::now()返回一個(gè)等于或大于absolute_time的值),線程接觸阻塞。
拋出
當(dāng)效果沒有達(dá)成時(shí),會(huì)拋出std::system_error異?;蛘哂蓀red拋出任意異常。
同步
std::condition_variable實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
當(dāng)當(dāng)前調(diào)用函數(shù)的線程退出時(shí),等待std::condition_variable的所有線程將會(huì)被喚醒。
聲明
void notify_all_at_thread_exit(
condition_variable& cv,unique_lock<mutex> lk);
先決條件
當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lk.owns_lock()必須為true。lk.mutex()需要返回的值要與并發(fā)等待線程相關(guān)的任意cv中鎖對(duì)象提供的wait(),wait_for()或wait_until()相同。
效果
將lk的所有權(quán)轉(zhuǎn)移到內(nèi)部存儲(chǔ)中,并且當(dāng)有線程退出時(shí),安排被提醒的cv類。這里的提醒等價(jià)于
lk.unlock();
cv.notify_all();
拋出
當(dāng)效果沒有達(dá)成時(shí),拋出std::system_error異常。
NOTE:在線程退出前,掌握著鎖的所有權(quán),所以這里要避免死鎖發(fā)生。這里建議調(diào)用該函數(shù)的線程應(yīng)該盡快退出,并且在該線程可以執(zhí)行一些阻塞的操作。用戶必須保證等地線程不會(huì)錯(cuò)誤的將喚醒線程當(dāng)做已退出的線程,特別是偽喚醒??梢酝ㄟ^等待線程上的謂詞測(cè)試來實(shí)現(xiàn)這一功能,在互斥量保護(hù)的情況下,只有謂詞返回true時(shí)線程才能被喚醒,并且在調(diào)用notify_all_at_thread_exit(std::condition_variable_any類中函數(shù))前是不會(huì)釋放鎖。
std::condition_variable_any類允許線程等待某一條件為true的時(shí)候繼續(xù)運(yùn)行。不過std::condition_variable只能和std::unique_lock<std::mutex>一起使用,std::condition_variable_any可以和任意可上鎖(Lockable)類型一起使用。
std::condition_variable_any實(shí)例不能進(jìn)行拷貝賦值(CopyAssignable)、拷貝構(gòu)造(CopyConstructible)、移動(dòng)賦值(MoveAssignable)或移動(dòng)構(gòu)造(MoveConstructible)。
class condition_variable_any
{
public:
condition_variable_any();
~condition_variable_any();
condition_variable_any(
condition_variable_any const& ) = delete;
condition_variable_any& operator=(
condition_variable_any const& ) = delete;
void notify_one() noexcept;
void notify_all() noexcept;
template<typename Lockable>
void wait(Lockable& lock);
template <typename Lockable, typename Predicate>
void wait(Lockable& lock, Predicate pred);
template <typename Lockable, typename Clock,typename Duration>
std::cv_status wait_until(
Lockable& lock,
const std::chrono::time_point<Clock, Duration>& absolute_time);
template <
typename Lockable, typename Clock,
typename Duration, typename Predicate>
bool wait_until(
Lockable& lock,
const std::chrono::time_point<Clock, Duration>& absolute_time,
Predicate pred);
template <typename Lockable, typename Rep, typename Period>
std::cv_status wait_for(
Lockable& lock,
const std::chrono::duration<Rep, Period>& relative_time);
template <
typename Lockable, typename Rep,
typename Period, typename Predicate>
bool wait_for(
Lockable& lock,
const std::chrono::duration<Rep, Period>& relative_time,
Predicate pred);
};
構(gòu)造一個(gè)std::condition_variable_any對(duì)象。
聲明
condition_variable_any();
效果
構(gòu)造一個(gè)新的std::condition_variable_any實(shí)例。
拋出
當(dāng)條件變量構(gòu)造成功,將拋出std::system_error異常。
銷毀std::condition_variable_any對(duì)象。
聲明
~condition_variable_any();
先決條件
之前沒有使用*this總的wait(),wait_for()或wait_until()阻塞過線程。
效果
銷毀*this。
拋出
無
std::condition_variable_any喚醒一個(gè)等待該條件變量的線程。
聲明
void notify_all() noexcept;
效果
喚醒一個(gè)等待*this的線程。如果沒有線程在等待,那么調(diào)用沒有任何效果
拋出
當(dāng)效果沒有達(dá)成,就會(huì)拋出std::system_error異常。
同步
std::condition_variable實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
喚醒所有等待當(dāng)前std::condition_variable_any實(shí)例的線程。
聲明
void notify_all() noexcept;
效果
喚醒所有等待*this的線程。如果沒有線程在等待,那么調(diào)用沒有任何效果
拋出
當(dāng)效果沒有達(dá)成,就會(huì)拋出std::system_error異常。
同步
std::condition_variable實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
通過std::condition_variable_any的notify_one()、notify_all()或偽喚醒結(jié)束等待。
聲明
template<typename Lockable>
void wait(Lockable& lock);
先決條件
Lockable類型需要能夠上鎖,lock對(duì)象擁有一個(gè)鎖。
效果
自動(dòng)解鎖lock對(duì)象,對(duì)于線程等待線程,當(dāng)其他線程調(diào)用notify_one()或notify_all()時(shí)被喚醒,亦或該線程處于偽喚醒狀態(tài)。在wait()返回前,lock對(duì)象將會(huì)再次上鎖。
拋出
當(dāng)效果沒有達(dá)成的時(shí)候,將會(huì)拋出std::system_error異常。當(dāng)lock對(duì)象在調(diào)用wait()階段被解鎖,那么當(dāng)wait()退出的時(shí)候lock會(huì)再次上鎖,即使函數(shù)是通過異常的方式退出。
NOTE:偽喚醒意味著一個(gè)線程調(diào)用wait()后,在沒有其他線程調(diào)用notify_one()或notify_all()時(shí),還處以蘇醒狀態(tài)。因此,建議對(duì)wait()進(jìn)行重載,在可能的情況下使用一個(gè)謂詞。否則,建議wait()使用循環(huán)檢查與條件變量相關(guān)的謂詞。
同步
std::condition_variable_any實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
等待std::condition_variable_any上的notify_one()或notify_all()被調(diào)用,或謂詞為true的情況,來喚醒線程。
聲明
template<typename Lockable,typename Predicate>
void wait(Lockable& lock,Predicate pred);
先決條件
pred()謂詞必須是合法的,并且需要返回一個(gè)值,這個(gè)值可以和bool互相轉(zhuǎn)化。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。
效果
正如
while(!pred())
{
wait(lock);
}
拋出
pred中可以拋出任意異常,或者當(dāng)效果沒有達(dá)到的時(shí)候,拋出std::system_error異常。
NOTE:潛在的偽喚醒意味著不會(huì)指定pred調(diào)用的次數(shù)。通過lock進(jìn)行上鎖,pred經(jīng)常會(huì)被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個(gè)值,在(bool)pred()評(píng)估后,返回true。
同步
std::condition_variable_any實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
std::condition_variable_any在調(diào)用notify_one()、調(diào)用notify_all()、超時(shí)或線程偽喚醒時(shí),結(jié)束等待。
聲明
template<typename Lockable,typename Rep,typename Period>
std::cv_status wait_for(
Lockable& lock,
std::chrono::duration<Rep,Period> const& relative_time);
先決條件
當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。
效果
當(dāng)其他線程調(diào)用notify_one()或notify_all()函數(shù)時(shí),或超出了relative_time的時(shí)間,亦或是線程被偽喚醒,則將lock對(duì)象自動(dòng)解鎖,并將阻塞線程喚醒。當(dāng)wait_for()調(diào)用返回前,lock對(duì)象會(huì)再次上鎖。
返回
線程被notify_one()、notify_all()或偽喚醒喚醒時(shí),會(huì)返回std::cv_status::no_timeout;反之,則返回std::cv_status::timeout。
拋出
當(dāng)效果沒有達(dá)成的時(shí)候,會(huì)拋出std::system_error異常。當(dāng)lock對(duì)象在調(diào)用wait_for()函數(shù)前解鎖,那么lock對(duì)象會(huì)在wait_for()退出前再次上鎖,即使函數(shù)是以異常的方式退出。
NOTE:偽喚醒意味著,一個(gè)線程在調(diào)用wait_for()的時(shí)候,即使沒有其他線程調(diào)用notify_one()和notify_all()函數(shù),也處于蘇醒狀態(tài)。因此,這里建議重載wait_for()函數(shù),重載函數(shù)可以使用謂詞。要不,則建議wait_for()使用循環(huán)的方式對(duì)與謂詞相關(guān)的條件變量進(jìn)行檢查。在這樣做的時(shí)候還需要小心,以確保超時(shí)部分依舊有效;wait_until()可能適合更多的情況。這樣的話,線程阻塞的時(shí)間就要比指定的時(shí)間長(zhǎng)了。在有這樣可能性的地方,流逝的時(shí)間是由穩(wěn)定時(shí)鐘決定。
同步
std::condition_variable_any實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
std::condition_variable_any在調(diào)用notify_one()、調(diào)用notify_all()、超時(shí)或線程偽喚醒時(shí),結(jié)束等待。
聲明
template<typename Lockable,typename Rep,
typename Period, typename Predicate>
bool wait_for(
Lockable& lock,
std::chrono::duration<Rep,Period> const& relative_time,
Predicate pred);
先決條件
pred()謂詞必須是合法的,并且需要返回一個(gè)值,這個(gè)值可以和bool互相轉(zhuǎn)化。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。
效果
正如
internal_clock::time_point end=internal_clock::now()+relative_time;
while(!pred())
{
std::chrono::duration<Rep,Period> remaining_time=
end-internal_clock::now();
if(wait_for(lock,remaining_time)==std::cv_status::timeout)
return pred();
}
return true;
返回
當(dāng)pred()為true,則返回true;當(dāng)超過relative_time并且pred()返回false時(shí),返回false。
NOTE: 潛在的偽喚醒意味著不會(huì)指定pred調(diào)用的次數(shù)。通過lock進(jìn)行上鎖,pred經(jīng)常會(huì)被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個(gè)值,在(bool)pred()評(píng)估后返回true,或在指定時(shí)間relative_time內(nèi)完成。線程阻塞的時(shí)間就要比指定的時(shí)間長(zhǎng)了。在有這樣可能性的地方,流逝的時(shí)間是由穩(wěn)定時(shí)鐘決定。
拋出
當(dāng)效果沒有達(dá)成時(shí),會(huì)拋出std::system_error異?;蛘哂蓀red拋出任意異常。
同步
std::condition_variable_any實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
std::condition_variable_any在調(diào)用notify_one()、調(diào)用notify_all()、指定時(shí)間內(nèi)達(dá)成條件或線程偽喚醒時(shí),結(jié)束等待
聲明
template<typename Lockable,typename Clock,typename Duration>
std::cv_status wait_until(
Lockable& lock,
std::chrono::time_point<Clock,Duration> const& absolute_time);
先決條件
Lockable類型需要能夠上鎖,lock對(duì)象擁有一個(gè)鎖。
效果
當(dāng)其他線程調(diào)用notify_one()或notify_all()函數(shù),或Clock::now()返回一個(gè)大于或等于absolute_time的時(shí)間,亦或線程偽喚醒,lock都將自動(dòng)解鎖,并且喚醒阻塞的線程。在wait_until()返回之前l(fā)ock對(duì)象會(huì)再次上鎖。
返回
線程被notify_one()、notify_all()或偽喚醒喚醒時(shí),會(huì)返回std::cv_status::no_timeout;反之,則返回std::cv_status::timeout。
拋出
當(dāng)效果沒有達(dá)成的時(shí)候,會(huì)拋出std::system_error異常。當(dāng)lock對(duì)象在調(diào)用wait_for()函數(shù)前解鎖,那么lock對(duì)象會(huì)在wait_for()退出前再次上鎖,即使函數(shù)是以異常的方式退出。
NOTE:偽喚醒意味著一個(gè)線程調(diào)用wait()后,在沒有其他線程調(diào)用notify_one()或notify_all()時(shí),還處以蘇醒狀態(tài)。因此,這里建議重載wait_until()函數(shù),重載函數(shù)可以使用謂詞。要不,則建議wait_until()使用循環(huán)的方式對(duì)與謂詞相關(guān)的條件變量進(jìn)行檢查。這里不保證線程會(huì)被阻塞多長(zhǎng)時(shí)間,只有當(dāng)函數(shù)返回false后(Clock::now()的返回值大于或等于absolute_time),線程才能解除阻塞。
同步
std::condition_variable_any實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。
std::condition_variable_any在調(diào)用notify_one()、調(diào)用notify_all()、謂詞返回true或指定時(shí)間內(nèi)達(dá)到條件,結(jié)束等待。
聲明
template<typename Lockable,typename Clock,
typename Duration, typename Predicate>
bool wait_until(
Lockable& lock,
std::chrono::time_point<Clock,Duration> const& absolute_time,
Predicate pred);
先決條件
pred()必須是合法的,并且其返回值能轉(zhuǎn)換為bool值。當(dāng)線程調(diào)用wait()即可獲得鎖的所有權(quán),lock.owns_lock()必須為true。
效果
等價(jià)于
while(!pred())
{
if(wait_until(lock,absolute_time)==std::cv_status::timeout)
return pred();
}
return true;
返回
當(dāng)調(diào)用pred()返回true時(shí),返回true;當(dāng)Clock::now()的時(shí)間大于或等于指定的時(shí)間absolute_time,并且pred()返回false時(shí),返回false。
NOTE:潛在的偽喚醒意味著不會(huì)指定pred調(diào)用的次數(shù)。通過lock進(jìn)行上鎖,pred經(jīng)常會(huì)被互斥量引用所調(diào)用,并且函數(shù)必須返回(只能返回)一個(gè)值,在(bool)pred()評(píng)估后返回true,或Clock::now()返回的時(shí)間大于或等于absolute_time。這里不保證調(diào)用線程將被阻塞的時(shí)長(zhǎng),只有當(dāng)函數(shù)返回false后(Clock::now()返回一個(gè)等于或大于absolute_time的值),線程接觸阻塞。
拋出
當(dāng)效果沒有達(dá)成時(shí),會(huì)拋出std::system_error異常或者由pred拋出任意異常。
同步
std::condition_variable_any實(shí)例中的notify_one(),notify_all(),wait(),wait_for()和wait_until()都是序列化函數(shù)(串行調(diào)用)。調(diào)用notify_one()或notify_all()只能喚醒正在等待中的線程。