티스토리 뷰
조건 변수는 메시지를 통한 스레드 동기화에 사용된다.
이때 condition_variable 헤더가 필요하다.
한 스레드가 메시지 발신자 역활을 하면 다른 스레드는 수신자가 된다.
수신자는 발신자가 보낸 알림을 기다리게 된다.
조건 변수의 전형적인 쓰임새는 발신자->수신자 또는 생산자>소비자 작업 흐름이다.
조건 변수는 메시지 발신자뿐만 아니라 수진자도 될 수 있다.
cv.notify_one() : 대기하고 있는 스레드에게 알림을 보낸다.
cv.notify_all() : 대기하고 있는 스레드 전체에게 알림을 보낸다.
cv.wait(lock, ...) : std::unique_lock 을 받고 알림을 기다린다.
cv.wait_for(lock, relTime, ...) : std::unique_lock 을 받고 어떤 기간 동안 알림을 기다린다.
cv.wait_until(lock, absTime, ...) : std::unique_lock 을 받고 어떤 시점까지 알림을 기다린다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
#include <iostream>
#include <condition_variable>
#include <mutex>
#include <thread>
std::mutex mutex_;
std::condition_variable condVar;
bool dataReady{ false };
void doTheWork() {
std::cout << "PRocessing shared data." << std::endl;
}
void waitingForWork() {
std::cout << "Worker : Wating for work." << std::endl;
std::unique_lock<std::mutex> lck(mutex_); // 수신자는 unique_lock 필요
// dataReady 값이 true면 조건 변수는 뮤텍스를 잠김 해제하고 그 다음 과정을 진행
// dataReady 값이 false 면 조건 변수는 뮤텍스를 잠김 해제하고 다시 대기 상태로 들어간다.
condVar.wait(lck, [] { return dataReady; });
doTheWork();
std::cout << "Work done." << std::endl;
}
void setDataReady() {
{
std::lock_guard<std::mutex> lck(mutex_); // 발신자는 잠김과 해제를 한번만 호출하기 때문에 lock_guard 로 충분
dataReady = true;
}
std::cout << "Sender : Data is ready." << std::endl;
condVar.notify_one();
}
int main()
{
std::cout << std::endl;
std::thread t1(waitingForWork);
std::thread t2(setDataReady);
t1.join();
t2.join();
std::cout << std::endl;
}
|
cs |
21행 : wait 가 처음 호출될때는 wait 호출은 뮤텍스를 잠그고 []{ return dataReady; } 하는 프레디킷(predicate) 이 true 인지 확인한다.
dataReady 값이 true 일 경우, 조건 변수는 뮤텍스를 잠김 해제하고 그 다음 과정을 진행하고
dataReady 값이 false 면 조건 변수는 뮤텍스를 잠김 해제하고 다시 대기 상태로 들어간다.
false 인 경우 대기 상태에서 발신자가 dataReady 값을 true 로 변경하고 메시지(알림)를 보낸 경우
다시 wait 호출하면 대기하는 스레드가 알림을 받고 뮤텍스 잠그고 프레디킷을 확인후 false 면 다시 대기, true 면 대기상태에서 털출한다.
실행결과>
Sender, Worker 바뀔 수 있음.
만약, 아래 그림과 같이 프레디킷 값이 없으면 수진자(Worker) 스레드가 먼저 실행되면 대기 상태에서 빠져 나오지 못하는 문제가 발생할 수 있다.