Namespaces
Variants

std::condition_variable_any:: wait

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 >
void wait ( Lock & lock ) ;
(1) (C++11부터)
template < class Lock, class Predicate >
void wait ( Lock & lock, Predicate pred ) ;
(2) (C++11부터)
template < class Lock, class Predicate >
bool wait ( Lock & lock, std:: stop_token stoken, Predicate pred ) ;
(3) (C++20부터)

wait 는 조건 변수가 통지되거나 허위 깨어남이 발생할 때까지 현재 스레드를 차단합니다. pred 는 허위 깨어남을 감지하기 위해 선택적으로 제공될 수 있습니다.

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

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

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

목차

매개변수

lock - 호출 스레드가 반드시 잠근 lock
stoken - 인터럽션을 등록할 stop token
pred - 대기가 완료될 수 있는지 확인하는 predicate
타입 요구사항
-
Lock BasicLockable 요구사항을 충족해야 함.
-
Predicate FunctionObject 요구사항을 충족해야 함.
-
pred ( ) 는 유효한 표현식이어야 하며, 그 타입과 값 카테고리는 BooleanTestable 요구사항을 충족해야 함.

반환값

1,2) (없음)
3) 호출자에게 반환되기 전 pred ( ) 의 최종 결과.

예외

1) 예외를 발생시키지 않습니다.
2,3) pred 에 의해 발생하는 모든 예외.

참고 사항

오버로드 (3) 의 반환 값은 pred true 로 평가되었는지 여부를 나타내며, 중단 요청이 있었는지 여부와 관계없습니다.

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 2114
( P2167R3 )
C++11 bool 변환 가능성이 구현의 기대를 반영하기에 너무 약함 요구 사항 강화됨
LWG 2135 C++11 lock. lock ( ) 가 예외를 발생시키는 경우 동작이 불명확했음 이 경우 std::terminate 호출

참고 항목

현재 스레드를 조건 변수가 깨어나거나 지정된 타임아웃 시간이 경과할 때까지 차단합니다
(public member function)
현재 스레드를 조건 변수가 깨어나거나 지정된 시간 점에 도달할 때까지 차단합니다
(public member function)
C documentation for cnd_wait

외부 링크

The Old New Thing 아티클: Win32 조건 변수에서의 가짜 깨어남.