Namespaces
Variants

std::condition_variable_any:: 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 Lock, class Clock, class Duration >

std:: cv_status
wait_until ( Lock & lock,

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

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

Predicate pred ) ;
(2) (C++11 이후)
template < class Lock, class Clock, class Duration, class Predicate >

bool wait_until ( Lock & lock, std:: stop_token stoken,
const std:: chrono :: time_point < Clock, Duration > & abs_time,

Predicate pred ) ;
(3) (C++20 이후)

wait_until 는 조건 변수가 통지될 때까지, 주어진 시간이 경과할 때까지, 또는 잘못된 깨어남이 발생할 때까지 현재 스레드를 차단합니다. pred 는 선택적으로 제공되어 잘못된 깨어남을 감지하는 데 사용될 수 있습니다.

1) 원자적으로 lock. unlock ( ) 를 호출하고 * this 에서 블록합니다.
스레드는 notify_all() 또는 notify_one() 가 실행되거나, abs_time 에 도달했을 때 차단 해제됩니다. 또한 가짜(spurious) 차단 해제가 발생할 수도 있습니다.
차단 해제되면 lock. lock ( ) 를 호출하고(락에서 차단될 수 있음), 이후 반환됩니다.
2,3) 특정 조건이 참이 될 때까지 대기하며, 잘못된 깨어남을 무시하는 데 사용할 수 있습니다.
2) 다음 코드와 동등합니다: while ( ! pred ( ) )
if ( wait_until ( lock, abs_time ) == std:: cv_status :: timeout )
return pred ( ) ;
return true ;
.
3) 이 호출 기간 동안 * this 를 등록하여 stoken 의 연관된 중단 상태에 대한 중단 요청이 있을 경우 알림을 받습니다; 그러면 다음과 동일합니다: while ( ! stoken. stop_requested ( ) )
{
if ( pred ( ) )
return true ;
if ( wait_until ( lock, abs_time ) == std:: cv_status :: timeout )
return pred ( ) ;
}
return pred ( ) ;
.

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

  1. 뮤텍스를 재잠금하는 과정에서 예외가 발생할 경우 이런 상황이 발생할 수 있습니다.

목차

매개변수

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

반환값

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

예외

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

참고 사항

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

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

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; // 이 뮤텍스는 세 가지 목적으로 사용됩니다:
                 // 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)
wait_until
현재 스레드를 조건 변수가 깨어나거나 지정된 시간 점에 도달할 때까지 차단합니다
(public member function)