[C++] Event

강병우·2023년 8월 7일
0

Event는 스레드 간 순위가 보장되지 않다보니, 이를 관리하기 위해 사용한다. 이를 스레드 동기화라고 한다.

스레드 동기화

Producer클래스가 데이터를 저장하고 Consumer클래스가 데이터를 읽는 소스코드가 있다고 가정해보자. 단순히 저장하고 읽으면 되지만, 시간이 오래 걸려 이를 동시에 작업을 시작하도록 했다.
하지만, Producer가 데이터를 저장하기 전에 Consumer가 데이터를 읽을 수 없기에 대기를 해야 한다. 여기서, ConsumerProducer의 작업이 끝날 때까지 기다려주는데 이를 동기화라고 한다. 이 작업을 Event객체에서 처리할 수 있다.

Event

Event객체는 0 혹은 1로 상태를 기억할 수 있는 커널 오브젝트이다. 생성 예시는 다음과 같다.

HANDLE handle = ::CreateEvent(NULL/*보안속성*/, FALSE/*bManualReset*/, FALSE/*binitialState*/, NULL);

첫번째 인자 : SECURITY_ATTRIBUTES구조체로 선언된 변수의 주소값이다. 이 객체는 보안 기술자의 계정 정보를 명시해야 한다(정확히는 모르겠으니 일단 NULL로 작성해도 상관없을 듯 하다)
두번째 인자 : TRUE값을 기입하면 이벤트 정보가 계속 유지되도록 한다. FALSE값이 들어가기 전까지 TRUE로 유지되는 이벤트 객체가 만들어진다.
세번째 인자 : 이벤트 객체의 초기값을 선언한다. 현재 이벤트 객체의 상태값을 가리킨다.
네번째 인자 : 이벤트 객체에 사용할 이름을 선언한다.

그 외 주로 사용되는 소스코드는 다음과 같다.

::SetEvent(handle);
::WaitForSingleObject(handle, INFINITE);
::CloseHandle(handle);

SetEvent : 현재 이벤트 상태값을 TRUE로 변경한다.
WaitSingleObject : 이벤트 상태값이 TRUE가 될 때까지 기다린다(인자값으로 상태를 넣을 수 있는데, INFINITE의 경우 무한히 대기한다)
CloseHandle: 이벤트 핸들값을 종료한다. 이벤트를 사용하고 종료해주면 된다.

예제 소스코드

#include "pch.h"
#include <iostream>
#include "CorePch.h"
#include <thread>
#include <atomic>
#include <mutex>
#include <windows.h>

mutex m;
queue<int32> q;
HANDLE handle;

void Producer()
{
	while (true)
	{
		unique_lock<mutex> lock(m);
		q.push(100);
	}
	::SetEvent(handle);
	//this_thread::sleep_for(100ms);
}

void Consumer()
{
	while (true)
	{
		::WaitForSingleObject(handle, INFINITE);

		unique_lock<mutex> lock(m);
		if (q.empty() == false)
		{
			int32 data = q.front();
			q.pop();
			cout << data << endl;
		}
	}
}


int main()
{
	// 커널 오브젝트
	// Usage Count
	// Signal (파란불) / Non-Signal (빨간불) << bool
	// Auto / Manual << bool

	handle = ::CreateEvent(NULL/*보안속성*/, FALSE/*bManualReset*/, FALSE/*binitialState*/, NULL);

	thread t1(Producer);
	thread t2(Consumer);

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

	::CloseHandle(handle);

}

1개의 댓글

comment-user-thumbnail
2023년 8월 7일

좋은 정보 감사합니다

답글 달기

관련 채용 정보