名稱空間
變體
操作

std::condition_variable_any::wait_for

來自 cppreference.com
 
 
併發支援庫
執行緒
(C++11)
(C++20)
this_thread 名稱空間
(C++11)
(C++11)
(C++11)
協同取消
互斥
(C++11)
通用鎖管理
(C++11)
(C++11)
(C++11)
(C++11)
(C++11)
條件變數
(C++11)
訊號量
門閂和屏障
(C++20)
(C++20)
期值
(C++11)
(C++11)
(C++11)
(C++11)
安全回收
(C++26)
危險指標
原子型別
(C++11)
(C++20)
原子型別的初始化
(C++11)(C++20 中已棄用)
(C++11)(C++20 中已棄用)
記憶體排序
(C++11)(C++26 中已棄用)
原子操作的自由函式
原子標誌的自由函式
 
 
template< class Lock, class Rep, class Period >

std::cv_status wait_for( Lock& lock,

                         const std::chrono::duration<Rep, Period>& rel_time );
(1) (C++11 起)
template< class Lock, class Rep, class Period, class Predicate >

bool wait_for( Lock& lock, const std::chrono::duration<Rep, Period>& rel_time,

               Predicate pred );
(2) (C++11 起)
template< class Lock, class Rep, class Period, class Predicate >

bool wait_for( Lock& lock, std::stop_token stoken,
               const std::chrono::duration<Rep, Period>& rel_time,

               Predicate pred );
(3) (C++20 起)

wait_for 使當前執行緒阻塞,直到條件變數被通知、給定的持續時間已過,或發生虛假喚醒。可以選擇提供 pred 以檢測虛假喚醒。

1) 等價於 return wait_until(lock, std::chrono::steady_clock::now() + rel_time);
2,3) 等待特定條件變為真,可用於忽略虛假喚醒。
2) 等價於 return wait_until(lock, std::chrono::steady_clock::now() + rel_time, std::move(pred));
3) 註冊 *this 在此呼叫期間,如果對 stoken 的關聯停止狀態發出停止請求,則會收到通知;然後它等價於 return wait_until(lock, std::move(stoken),
                  std::chrono::steady_clock::now() + rel_time, std::move(pred));

wait_for 返回後,lock 由呼叫執行緒鎖定。如果此後置條件無法滿足[1],則呼叫 std::terminate

  1. 這可能發生於對互斥體重新加鎖時丟擲異常。

目錄

[編輯] 引數

lock - 一個必須被呼叫執行緒鎖定的鎖
stoken - 一個停止令牌,用於註冊中斷
rel_time - 最大等待時長
pred - 用於檢查是否可以完成等待的謂詞
型別要求
-
Lock 必須滿足 BasicLockable 的要求。
-
Predicate 必須滿足函式物件 (FunctionObject) 的要求。
-
pred() 必須是有效表示式,其型別和值類別必須滿足 BooleanTestable 要求。

[編輯] 返回值

1) 如果自此呼叫開始以來 rel_time 已過,則為 std::cv_status::timeout,否則為 std::cv_status::no_timeout
2,3) 返回給呼叫者之前 pred() 的最新結果。

[編輯] 異常

1) 與超時相關的異常。
2,3) 與超時相關的異常,以及 pred 丟擲的任何異常。

[編輯] 注意

即使在鎖下收到通知,過載 (1) 在因超時返回時,也不保證關聯謂詞的狀態。

notify_one()/notify_all() 的效果以及 wait()/wait_for()/wait_until() 的三個原子部分(解鎖+等待、喚醒和鎖定)都以單一總順序發生,可以看作原子變數的 修改順序:此順序特定於此單個條件變數。這使得 notify_one() 不可能(例如)延遲並解除阻塞在呼叫 notify_one() 之後才開始等待的執行緒。

[編輯] 示例

#include <chrono>
#include <condition_variable>
#include <iostream>
#include <thread>
 
std::condition_variable_any cv;
std::mutex cv_m; // This mutex is used for three purposes:
                 // 1) to synchronize accesses to i
                 // 2) to synchronize accesses to std::cerr
                 // 3) for the condition variable cv
int i = 0;
 
void waits()
{
    std::unique_lock<std::mutex> lk(cv_m);
    std::cerr << "Waiting... \n";
    cv.wait(lk, []{ return i == 1; });
    std::cerr << "...finished waiting. i == 1\n";
}
 
void signals()
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    {
        std::lock_guard<std::mutex> lk(cv_m);
        std::cerr << "Notifying...\n";
    }
    cv.notify_all();
 
    std::this_thread::sleep_for(std::chrono::seconds(1));
 
    {
        std::lock_guard<std::mutex> lk(cv_m);
        i = 1;
        std::cerr << "Notifying again...\n";
    }
    cv.notify_all();
}
 
int main()
{
    std::thread t1(waits), t2(waits), t3(waits), t4(signals);
    t1.join(); 
    t2.join(); 
    t3.join();
    t4.join();
}

可能的輸出

Waiting...
Waiting...
Waiting...
Notifying...
Notifying again...
...finished waiting. i == 1
...finished waiting. i == 1
...finished waiting. i == 1

[編輯] 缺陷報告

下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。

缺陷報告 應用於 釋出時的行為 正確的行為
LWG 2093 C++11 規範中缺少與超時相關的異常 提及這些異常
LWG 2114
(P2167R3)
C++11 可轉換為 bool 對於反映實現的期望來說太弱了 要求已加強
LWG 2135 C++11 如果 lock.lock() 丟擲異常,則行為不明確 在這種情況下呼叫 std::terminate

[編輯] 參閱

阻塞當前執行緒直到條件變數被喚醒
(public member function) [編輯]
阻塞當前執行緒,直到條件變數被喚醒或達到指定的時間點。
(public member function) [編輯]