公有成員函式
<condition_variable>

std::condition_variable::wait_until

無條件 (1)
template <class Clock, class Duration>  cv_status wait_until (unique_lock<mutex>& lck,                        const chrono::time_point<Clock,Duration>& abs_time);
謂詞 (2)
template <class Clock, class Duration, class Predicate>       bool wait_until (unique_lock<mutex>& lck,                        const chrono::time_point<Clock,Duration>& abs_time,                        Predicate pred);
等待直到通知或指定時間點
當前執行緒的執行(該執行緒應已鎖定 lck互斥量)被阻塞,直到通知或直到 abs_time,以先發生者為準。

線上程阻塞時,該函式會自動呼叫 lck.unlock(),允許其他已鎖定的執行緒繼續執行。

一旦被通知或一旦到達 abs_time,函式將解除阻塞並呼叫 lck.lock(),使 lck 保持在呼叫函式時的狀態。然後函式返回(請注意,此最後的互斥量鎖定可能會在返回前再次阻塞該執行緒)。

通常,函式透過另一個執行緒呼叫成員函式 notify_onenotify_all 來喚醒。但某些實現可能會產生虛假喚醒,而無需呼叫這些函式。因此,此函式的使用者應確保其恢復條件已滿足。

如果指定了 pred (2),則僅當 pred 返回 false 時,該函式才會阻塞,並且只有在 pred 變為 true 時通知才能解除執行緒阻塞(這對於防止虛假喚醒尤其有用)。其行為如同實現為:
1
2
3
4
while (!pred())
  if ( wait_until(lck,abs_time) == cv_status::timeout)
    return pred();
return true;

引數

lck
一個 unique_lock 物件,其互斥量物件當前被該執行緒鎖定。
所有對此物件的wait成員函式的併發呼叫都必須使用相同的底層互斥量物件(透過 lck.mutex() 返回)。
abs_time
一個時間點,執行緒將在該時間點停止阻塞,允許函式返回。
time_point 是表示特定絕對時間的物件。
pred
一個可呼叫物件或函式,它不接受任何引數,並返回一個可以被評估為 bool 的值。
此函式會反覆呼叫 pred,直到其求值為 true

返回值

無條件版本 (1) 如果函式由於 abs_time 已到而返回,則返回 cv_status::timeout;否則返回 cv_status::no_timeout
謂詞版本 (2) 返回 pred(),而不管超時是否被觸發(儘管它只有在被觸發時才能為 false)。

資料競爭

該函式執行三個原子操作:
  • lck 的初始解鎖和同時進入等待狀態。
  • 解除等待狀態。
  • 在返回前鎖定 lck
對物件的原子操作按照一個單一的總順序進行排序,此函式中的三個原子操作以與上述相同的相對順序發生。

異常安全

如果任何引數的值對此函式無效(例如,如果 lck互斥鎖物件未被呼叫執行緒鎖定),則會導致未定義行為

否則,如果丟擲異常,則 condition_variable 物件和引數都處於有效狀態(基本保證)。

在失敗時可能丟擲 system_error(將任何錯誤條件從相應的 lockunlock 呼叫中傳遞)。

謂詞版本 (2) 也可能丟擲由 pred 丟擲的任何異常。

發生異常時,在退出函式作用域之前,會嘗試恢復 lck 的狀態(透過呼叫 lck.lock())。
如果與 abs_time 相關的操作丟擲異常,則此函式可能丟擲異常(請注意,在 <chrono> 中提供的標準 時鐘持續時間 型別上的操作永遠不會丟擲)。

謂詞版本 (2) 也可能丟擲由 pred 丟擲的異常。

如果函式在某個時刻未能恢復鎖定並返回(例如,如果嘗試鎖定或解鎖時丟擲異常),則會呼叫 std::terminate

另見