名稱空間
變體
操作

std::condition_variable::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 Rep, class Period >

std::cv_status wait_for( std::unique_lock<std::mutex>& lock,

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

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

               Predicate pred );
(2) (C++11 起)

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

1) 等價於 return wait_until(lock, std::chrono::steady_clock::now() + rel_time);
2) 等價於 return wait_until(lock, std::chrono::steady_clock::now() + rel_time, std::move(pred));
此過載可用於忽略虛假喚醒,同時等待特定條件變為真。

wait_for 返回後,lock.owns_lock()true,並且 lock.mutex() 被呼叫執行緒鎖定。如果這些後置條件無法滿足[1],則呼叫 std::terminate

如果滿足以下任何條件,則行為是未定義的:

  • lock.owns_lock()false
  • lock.mutex() 未被呼叫執行緒鎖定。
  • 如果其他執行緒也在 *this 上等待,則 lock.mutex() 不同於那些執行緒在 *this 上呼叫的等待函式(waitwait_forwait_until)所解鎖的互斥量。
  1. 這可能發生於對互斥體重新加鎖時丟擲異常。

目錄

[編輯] 引數

lock - 必須由呼叫執行緒鎖定的鎖
rel_time - 最長等待時間
pred - 用於檢查是否可以完成等待的謂詞
型別要求
-
Predicate 必須滿足函式物件 (FunctionObject) 的要求。
-
pred() 必須是有效的表示式,並且其型別和值類別必須滿足 BooleanTestable 要求。

[編輯] 返回值

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

[編輯] 異常

1) 與超時相關的異常。
2) 與超時相關的異常,以及由 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 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

[編輯] 另請參閱

阻塞當前執行緒直到條件變數被喚醒
(公共成員函式) [編輯]
阻塞當前執行緒,直到條件變數被喚醒或達到指定的時間點。
(公共成員函式) [編輯]