public member function
<condition_variable>

std::condition_variable::wait_for

無條件 (1)
template <class Rep, class Period>  cv_status wait_for (unique_lock<mutex>& lck,                      const chrono::duration<Rep,Period>& rel_time);
謂詞 (2)
template <class Rep, class Period, class Predicate>       bool wait_for (unique_lock<mutex>& lck,                      const chrono::duration<Rep,Period>& rel_time, Predicate pred);
等待超時或直到被通知
當前執行緒的執行(該執行緒應已鎖定 lck互斥鎖)在 rel_time 時間內被阻塞,或者直到被通知(如果後者先發生)。

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

一旦被通知rel_time 時間過去,該函式將解除阻塞並呼叫 lck.lock(),使 lck 處於呼叫函式時的相同狀態。然後函式返回(請注意,最後這個互斥鎖鎖定操作可能會在返回前再次阻塞執行緒)。

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

如果指定了 pred (2),則僅當 pred 返回 false 時,函式才會阻塞,並且只有當 pred 變為 true 時,通知才能解除執行緒的阻塞(這在對抗虛假喚醒時特別有用)。它的行為相當於以下實現:
1
return wait_until (lck, chrono::steady_clock::now() + rel_time, std::move(pred));

引數

lck
一個 unique_lock 物件,其互斥量物件當前被該執行緒鎖定。
所有對此物件的wait成員函式的併發呼叫都必須使用相同的底層互斥量物件(透過 lck.mutex() 返回)。
rel_time
執行緒等待被通知的最長可能時間間隔。
duration 是一個表示特定相對時間的物件。
pred
一個可呼叫物件或函式,它不接受任何引數,並返回一個可以被評估為 bool 的值。
此函式會反覆呼叫 pred,直到其求值為 true

返回值

無條件版本 (1) 返回 cv_status::timeout 表示函式因 rel_time 超時而返回,否則返回 cv_status::no_timeout
謂詞版本 (2) 返回 pred(),而不管超時是否被觸發(儘管它只有在被觸發時才能為 false)。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// condition_variable::wait_for example
#include <iostream>           // std::cout
#include <thread>             // std::thread
#include <chrono>             // std::chrono::seconds
#include <mutex>              // std::mutex, std::unique_lock
#include <condition_variable> // std::condition_variable, std::cv_status

std::condition_variable cv;

int value;

void read_value() {
  std::cin >> value;
  cv.notify_one();
}

int main ()
{
  std::cout << "Please, enter an integer (I'll be printing dots): \n";
  std::thread th (read_value);

  std::mutex mtx;
  std::unique_lock<std::mutex> lck(mtx);
  while (cv.wait_for(lck,std::chrono::seconds(1))==std::cv_status::timeout) {
    std::cout << '.' << std::endl;
  }
  std::cout << "You entered: " << value << '\n';

  th.join();

  return 0;
}

可能的輸出

Please, enter an integer (I'll be priniting dots):
.
.
7
You entered: 7


資料競爭

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

異常安全

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

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

在失敗的情況下,它可能丟擲 system_error(將來自相應 lockunlock 呼叫的任何錯誤條件傳遞)。

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

發生異常時,在退出函式作用域之前,會嘗試恢復 lck 的狀態(透過呼叫 lck.lock())。
如果與 rel_time 相關的操作丟擲異常,它也可能丟擲異常(請注意,<chrono> 提供的 duration 型別(如 seconds)的操作永遠不會丟擲異常)。

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

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

另見