condition_variable_any — std::condition_variable_any

condition_variable_any — std::condition_variable_any

std::condition_variable_any 클래스는 std::condition_variable의 일반화예요. C++11에서 도입됐어요. <condition_variable> 헤더에 있어요.

std::condition_variablestd::unique_lock<std::mutex>에서만 동작하는 반면, condition_variable_anyLockable 요구사항을 만족하는 어떤 락에서도 동작할 수 있어요 (예: std::shared_lock).

출처: cppreference

본문

// <condition_variable> 헤더, C++11
class condition_variable_any;

사용 예 — 일반화된 락

#include <condition_variable>
#include <shared_mutex>
#include <iostream>

std::mutex m;
std::condition_variable_any cv;
bool ready = false;

void produce() {
    {
        std::lock_guard<std::mutex> lk(m);
        ready = true;
    }
    cv.notify_one();
}

void consume() {
    std::unique_lock<std::mutex> lk(m);
    cv.wait(lk, []{ return ready; });   // ready가 될 때까지 대기
    std::cout << "consumed\n";
}

condition_variable_anyshared_lock과도 쓸 수 있어서(공유 모드 대기) shared_mutex 기반 시나리오에 유용해요.

std::shared_mutex sm;
std::condition_variable_any cv2;
// 공유 락에서 대기
std::shared_lock<std::shared_mutex> lk(sm);
cv2.wait(lk, []{ return false; });

특징

  • wait, wait_for, wait_until, notify_one, notify_all을 제공해요.
  • 어떤 Lockable 타입과도 사용 가능 → 유연하지만 condition_variable보다 약간의 오버헤드가 있을 수 있어요.
  • std::condition_variable이 더 특화되어 보통은 더 효율적이에요. 일반적 락이 필요할 때 _any를 써요.
std::condition_variable_any cv3;
std::mutex m2;
bool flag = false;
// 람다 predicate로 스퍼리어스 웨이크업 방지
std::unique_lock<std::mutex> lk(m2);
cv3.wait_for(lk, std::chrono::seconds(1), []{ return flag; });

condition_variable_any는 락 타입에 구애받지 않고 쓰고 싶을 때 선택해요. 기본 뮤텍스 기반 대기에는 std::condition_variable이 일반적이에요.

더 알아보기 (Learn more)

cppreference