Skip to content

Std::condition variable

때로 다른 스레드에서 수행하는 작업들이 서로를 기다려야 할 때가 있다. condition_variable를 사용하면 특정 조건이 만족될 때까지 스레드를 블록킹할 수 있는데 이 때 해제 조건을 다른 스레드에서 설정할 수도 있고 타임아웃을 지정할 수도 있다. condition_variable는 결과적으로 스레드간 통신을 가능하게 해준다. condition_variable는 WIn32 API에서 이벤트 객체를 생각하면 된다.

How to use

condition_variablewait()조건에 포함된 모든 변수는 wait()로 넘겨주는 std::mutex를 공유해야 한다.

The common use of condition vars is something like:

// THREAD 01:
    pthread_mutex_lock(&mutex);
    while (!condition)
        pthread_cond_wait(&cond, &mutex);
    /* do something that requires holding the mutex and condition is true */
    pthread_mutex_unlock(&mutex);

// THREAD 02:
    pthread_mutex_lock(&mutex);
    /* do something that might make condition true */
    pthread_cond_signal(&cond);
    pthread_mutex_unlock(&mutex);

Example

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

using namespace std;

static mutex _m;
static mutex _ms;
static condition_variable _cv;

void print(string const & str)
{
    lock_guard<mutex> guard(_ms);
    cout << str << endl;
}

void print(string const & str, thread::id const & id)
{
    lock_guard<mutex> guard(_ms);
    cout << str << id << endl;
}

void runner()
{
    unique_lock<mutex> locker(_m);
    print("Runner prefix wait(): ", this_thread::get_id());
    _cv.wait(locker);
    print("Runner suffix wait(): ", this_thread::get_id());
}

void runner2()
{
    for (int i = 0; i < 3; ++i) {
        print("prefix sleep.");
        this_thread::sleep_for(chrono::milliseconds(1000));
        print("suffix sleep.");
        _cv.notify_one();
        print("notify one.");
    }
}

int main()
{
    thread t1([&](){ runner(); });
    thread t2([&](){ runner(); });
    thread t3([&](){ runner2(); });

    t1.join();
    t2.join();
    t3.join();

    return 0;
}

OUTPUT: (보기 쉽도록 하기 위해, 동작이 없을 때 개행을 추가함)

prefix sleep.
Runner prefix wait(): 0x700000081000
Runner prefix wait(): 0x700000104000

suffix sleep.
notify one.
prefix sleep.
Runner suffix wait(): 0x700000081000

suffix sleep.
notify one.
prefix sleep.
Runner suffix wait(): 0x700000104000

suffix sleep.
notify one.

Favorite site

References


  1. Blog.naver_-jidon333-_condition_variable.pdf