하아찡
[C++ 11] condition variable(조건 변수) 본문
안녕하세요.
이번에는 condition variable를 알아보겠습니다.
이전에 알아봤던 Event에서 CreateEvent를 사용해서 커널단에 이벤트를 등록하는 방식으로 처리를 해봤습니다.
해당방식은 다른 프로세스에게도 이벤트를 전달 할 수 있는데, 나는 내 프로그램 내부에서만 처리가능하면 될거같은데 너무 무겁게 작업하는거 아닌가? 라는 생각을 할 수 있습니다.
그래서 있는게 condition variable입니다.
condition variable는 유저 모드 이벤트를 생성 및 호출을 하게 가능하게 됩니다.
사실 유저모드에서 이벤트가 발생하고 처리가 되는건 아닙니다. 실질적으로 이벤트가 발생했을때는 커널모드의 개입이 필요한데 그 외의 작업들이 유저모드에서 처리가 되기때문에 CreateEvent를 사용해서 이벤트를 생성하는 방식보다 훨씬 더 가볍습니다.
일다 그러면 사용방법을 보시죠
condition variable 맴버함수에는
wait와 notify_one가 있습니다. 물론 더있는데 두가지만 살펴보겠습니다.
notify_once는 기다리고있는 쓰레드 한개를 깨워서 진행하게 합니다.
wait는 condition variable를 통해서 통지를 받기전까지 대기를합니다.
통지를 받아도 추가적으로 조건이 맞아야 작동하게도 할 수 있습니다.
더욱 다양한 함수를 살펴보시고싶으면 밑에 블로그를 추천드리겠습니다.
https://jungwoong.tistory.com/92
[c++] condition variable(조건 변수)
이번 글에서는 std::condition_variable에 대해서 설명드립니다. 설명 및 기본 동작 std::condition_variable condition_variable 클래스는 다른 스레드가 공유 변수를 수정하고 condition_variable로 통지할 때까지 스레
jungwoong.tistory.com
void wait(unique_lock<mutex>& _Lck);
template <class _Predicate>
void wait(unique_lock<mutex>& _Lck, _Predicate _Pred);
wait를 잘 살펴보면 wait는 lock_gurad를 사용하지못합니다. 대신 다른 unique_lock을 사용하게 되는데,
그 이유는 unique_lock은 Lock을 잡는 시점을 설정을 할 수 있습니다. 해당 이유로 lock_gurad대신 unique_lock을 사용하셔서 전달시켜 줘야합니다.
#include "pch.h"
#include <thread>
#include <atomic>
#include <mutex>
#include <Windows.h>
#include <condition_variable>
condition_variable cv;
queue<int32> q;
mutex m;
void Producer() {
while (true) {
{
unique_lock<mutex> guard(m);
q.push(100);
}
cv.notify_one();
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
}
void Consumer(int32 index) {
while (true) {
unique_lock<mutex> guard(m);
cv.wait(guard, []() {return q.empty() == false; }); //한번더 확인 틀리면 lock을 다시 해제하고 대기상태.
if (q.empty() == false) {
//값이 있으면 빼온다
int32 data = q.front();
q.pop();
cout << data << endl;
}
}
}
int main()
{
std::thread t1(Producer);
std::thread t2(Consumer,1);
std::thread t3(Consumer,2);
std::thread t4(Consumer,3);
std::thread t5(Consumer,4);
if (t1.joinable()) {
t1.join();
}
if (t2.joinable()) {
t2.join();
}
if (t3.joinable()) {
t3.join();
}
if (t4.joinable()) {
t4.join();
}
if (t5.joinable()) {
t5.join();
}
}
저는 wait에 조건부를 사용한 방식을 보여드리겠습니다.
주석처리를 해두었지만 다시한번 살펴보면
cv.wait(guard, []() {return q.empty() == false; });
위코드를 보면 wait로 락을 잡았어도
q.empty() == false가 맞지 않으면 잡았던 락을 풀어버립니다.
'C++ > 추가공부' 카테고리의 다른 글
[C++] 메모리 모델 (0) | 2024.12.27 |
---|---|
[C++] Event (0) | 2024.12.27 |
[C++ 11] SleepLock (1) | 2024.12.27 |
[C++ 11]std::atomic, SpinLock (1) | 2024.12.27 |
Volatile 예약어 (0) | 2024.10.30 |