Namespaces
Variants

std::condition_variable:: wait_until

From cppreference.net
Concurrency support library
Threads
(C++11)
(C++20)
this_thread namespace
(C++11)
(C++11)
Cooperative cancellation
Mutual exclusion
Generic lock management
Condition variables
(C++11)
Semaphores
Latches and Barriers
(C++20)
(C++20)
Futures
(C++11)
(C++11)
(C++11)
Safe reclamation
Hazard pointers
Atomic types
(C++11)
(C++20)
Initialization of atomic types
(C++11) (deprecated in C++20)
(C++11) (deprecated in C++20)
Memory ordering
(C++11) (deprecated in C++26)
Free functions for atomic operations
Free functions for atomic flags
template < class Clock, class Duration >

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

const std:: chrono :: time_point < Clock, Duration > & abs_time ) ;
(1) (C++11 이후)
template < class Clock, class Duration, class Predicate >

bool wait_until ( std:: unique_lock < std:: mutex > & lock,
const std:: chrono :: time_point < Clock, Duration > & abs_time,

Predicate pred ) ;
(2) (C++11 이후)

wait_until 는 현재 스레드가 조건 변수가 통지될 때까지, 주어진 시간 포인트에 도달할 때까지, 또는 가짜 깨어남이 발생할 때까지 블록되도록 합니다. pred 는 가짜 깨어남을 감지하기 위해 선택적으로 제공될 수 있습니다.

1) 원자적으로 lock. unlock ( ) 를 호출하고 * this 에서 블록합니다.
스레드는 notify_all() 또는 notify_one() 가 실행되거나, abs_time 에 도달했을 때 차단 해제됩니다. 가짜 차단 해제(spuriously unblocked)될 수도 있습니다.
차단 해제되면 lock. lock ( ) 를 호출하고(락에서 차단될 수 있음), 그 후 반환됩니다.
2) 다음 코드와 동등함: while ( ! pred ( ) )
if ( wait_until ( lock, abs_time ) == std:: cv_status :: timeout )
return pred ( ) ;
return true ;
.
이 오버로드는 특정 조건이 참이 될 때까지 대기하는 동안 잘못된 깨어남을 무시하는 데 사용될 수 있습니다.

wait_until 이 반환된 직후, lock. owns_lock ( ) true 이며, lock. mutex ( ) 는 호출 스레드에 의해 잠겨 있습니다. 이러한 사후 조건이 충족될 수 없는 경우 [1] , std::terminate 를 호출합니다.

다음 조건 중 하나라도 충족되면, 동작은 정의되지 않습니다:

  • lock. owns_lock ( ) false 인 경우.
  • lock. mutex ( ) 이 호출 스레드에 의해 잠겨 있지 않은 경우.
  • 다른 스레드들도 * this 를 기다리고 있을 때, lock. mutex ( ) 이 해당 스레드들이 * this 에서 호출한 대기 함수들( wait , wait_for wait_until )에 의해 잠금 해제된 뮤텍스와 다른 경우.
  1. 뮤텍스를 재잠금하는 과정에서 예외가 발생할 경우 이런 상황이 발생할 수 있습니다.

목차

매개변수

lock - 호출 스레드가 반드시 잠근 lock
abs_time - 대기가 만료되는 시간 지점
pred - 대기 완료 여부를 확인하는 predicate
타입 요구사항
-
Predicate FunctionObject 요구사항을 충족해야 함.
-
pred ( ) 는 유효한 표현식이어야 하며, 해당 타입과 값 범주는 BooleanTestable 요구사항을 충족해야 함.

반환값

1) std:: cv_status :: timeout 만약 abs_time 에 도달한 경우, 그렇지 않으면 std:: cv_status :: no_timeout .
2) 호출자에게 반환되기 전의 pred ( ) 최신 결과.

예외

1) 타임아웃 관련 예외.
2) 타임아웃 관련 예외 및 pred 에서 발생하는 모든 예외.

참고 사항

표준은 abs_time 에 연결된 클럭을 사용하여 시간을 측정할 것을 권장합니다; 해당 클럭이 단조 클럭일 필요는 없습니다. 클럭이 불연속적으로 조정되는 경우 이 함수의 동작에 대한 보장은 없지만, 기존 구현들은 abs_time Clock 에서 std::chrono::system_clock 으로 변환하고 POSIX pthread_cond_timedwait 에 위임하여 시스템 클럭에 대한 조정은 준수하지만 사용자가 제공한 Clock 에 대한 조정은 준수하지 않습니다. 어떤 경우든, 이 함수는 스케줄링 또는 자원 경합 지연으로 인해 abs_time 이 경과한 이후까지 더 오래 대기할 수도 있습니다.

사용 중인 클록이 std::chrono::steady_clock 또는 다른 모노토닉 클록이라 하더라도, 시스템 클록 조정이 가짜 웨이크업(spurious wakeup)을 유발할 수 있습니다.

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; // 이 뮤텍스는 세 가지 목적으로 사용됩니다:
                 // 1) i에 대한 접근 동기화
                 // 2) std::cerr에 대한 접근 동기화
                 // 3) 조건 변수 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++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
LWG 2093 C++11 타임아웃 관련 예외가 명세에서 누락됨 해당 예외들을 명시함
LWG 2114
( P2167R3 )
C++11 bool 변환 가능성이 구현들의 기대를 반영하기에 너무 약함 요구 사항 강화됨
LWG 2135 C++11 lock. lock ( ) 가 예외를 발생시킬 경우 동작이 불명확함 이 경우 std::terminate 호출

참고 항목

조건 변수가 깨어날 때까지 현재 스레드를 차단합니다
(public member function)
조건 변수가 깨어나거나 지정된 시간 제한이 경과할 때까지 현재 스레드를 차단합니다
(public member function)