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