Condition Variable

원래벌레·2022년 6월 26일
0
post-custom-banner

💎 Condition Variable

  • Condition Variable은 thread 스케쥴러의 event 방식과 비슷합니다. 또한 event 방식보다는 lock을 다루기에 더 일반적인 방법입니다.

  • Condition Variable과 thread 스케쥴러의 event 방식과의 차이점은 후자는 커널레벨에서의 오브젝트라면 Condition Variable은 유저레벨에서의 오브젝트라는 점입니다.

  • 그렇기 때문에 event를 이용한 방법을 통해서는 프로그램과 프로그램 사이의 상호동작을 다룰 수 있지만 Condition Variable을 통해서는 하나의 프로그램 내에서만 상호동작을 다룰 수 있습니다. 하지만 게임을 개발한다는 범위 내에서는 Condition Variable을 통해서 작업을 못하는 부분은 없습니다.

💍 Condition Variable의 예제 코드

#include "pch.h"
#include <iostream>
#include "CorePch.h"
#include <thread>
#include <mutex>
#include <windows.h>
using namespace std;

mutex m;
queue<int32> q;
condition_variable cv;

void Producer()
{
	while (true)
	{
		{
			unique_lock<mutex> lock(m);
			q.push(100);
		}

		cv.notify_one();
	}

}

void Consumer()
{
	while (true)
	{
		unique_lock<mutex> lock(m);
		cv.wait(lock, []() { return q.empty() == false; });

		int32 data = q.front();
		q.pop();
		cout << q.size() << endl;
	}
}

int main()
{
	thread t1(Producer);
	thread t2(Consumer);

	t1.join();
	t2.join();
};

💍 코드의 대한 설명

  • Condition Variable에는 한가지 특징이 있습니다. 그것은 Lock과 짝을지어 동작을 한다는 것입니다.

  • 이러한 특징 때문에 Condition Variable은 일반적인 동작패턴을 가지고 있습니다.

Producer의 일반적인 동작
(1) Lock을 잡는다.
(2) 공유 변수 값을 수정한다.
(3) Lock을 풀어준다.
(4) 조건 변수를 통해 다른 쓰레드에게 통지한다.

Producer 함수에서 unique_lock을 사용한 것이 1번의 내용이고, while문 내의 {} 부분이 2번의 내용이다. 그리고 Lock을 풀어주는 부분 3번은 unique_lock의 소멸자 부분이며, 4번이 notify()부분이다.

Consumer의 일반적인 동작
(1) Lock을 잡는다.
(2) 조건을 확인
-만족 : 빠져 나와서 이어서 코드를 진행한다.
-불만족 : Lock을 풀어주고 대기상태로 들어간다.

Consumer 함수의 unique_lock을 선언해주는 부분이 1번의 내용이다. 그리고 2번의 내용이 cv.wait 부분이다. 여기서 Codition Variable의 wait 메소드는 인수로 unique_lock과 람다형식의 조건식을 받는다.

💍 참고사항

  • 만약에 wait을 가진 여러 Consumer가 있다고 했을 때, notify_one이 들어오게 되면, Consumer들은 경합을 하게되고, 이 과정에서 패배자는 다시 수면에 들게된다.

  • 위 경우가 아닌 이미 wait을 차지한 즉 경합에서 승리한 Consumer가 Lock을 잡지 못 하는 경우 즉 Producer가 먼저 Lock을 차지해가거나, 다른 쓰레드가 Lock을 차지하는 경우에는 while문을 통해서 Lock을 차지하려 한다.

profile
학습한 내용을 담은 블로그 입니다.
post-custom-banner

0개의 댓글