Language/C++

[C++] std::condition_variable

어발 2025. 7. 14. 23:04
std::condition_variable
- 신호(signal) 기반의 동기화 도구
- <condition_variable> 헤더
- std::unique_lock를 사용해야 한다.

std::condition_variable의 기본구조

Producer - Consumer 구조로 공유자원에 생산자 데이터가 쓰여지면 소비자에서 소비한다.

condition_variable은 unique_lock를 기본적으로 사용함에 유의한다.

// Consumer
std::mutex m;

std::unique_lock<std::mutex> ul(m);
cv.wait(ul);

// Producer
cv.notify_one();

std::condition_variable::wait

1. wait(std::unique_lock ul);

  - wait 함수 내부에서 unique_lock을 unlock하고 signal을 대기한다.

 

2. wait(std::unique_lock ul, Predicate pred);

 - 조건자 함수인 pred를 넘기게 되면 pred가 true이면 기다리지않고 pred가 false면 signal을 대기한다.

std::condition_variable의 일반적 사용예시

#include <iostream>
#include <mutex>
#include <thread>
#include <chrono>
#include <condition_variable>

std::mutex m;
std::condition_variable cv;
bool data_ready = false;
int shared_data = 0;

void consumer() {
    std::unique_lock<std::mutex> ul(m);
    
    cv.wait(ul, []{return data_ready;});
    
    std::cout << "consume: " << shared_data << std::endl;
}

void producer() {
    {
        std::lock_guard<std::mutex> lg(m);
        shared_data = 100;
        data_ready = true;
        std::cout << "producer: " << shared_data << std::endl;
    }
    cv.notify_one();
}

int main() {
    std::thread t1(consumer);
    std::thread t2(producer);
    t1.join();
    t2.join();
}

std::condition_variable을 notify하는 방법

깨우는 방법은 두가지가 있는데, notify_one() 혹은 notify_all()을 사용하는 것이다.

notify_one()은 random하게 wait()중인 condition_variable을 깨우는 함수이고

notify_all()은 모든 wait()중인 condition_variable을 깨운다.

728x90