https://www.hanbit.co.kr/store/books/look.php?p_code=B7673779595
뇌를 자극하는 윈도우즈 시스템 프로그래밍
이 책은 거의 모든 개발자가 궁금해 하면서도 또한 상당히 어려워하는 컴퓨터 구조, 운영체제, 시스템 프로그래밍의 내용 중 꼭 필요한 부분만 간추려서 담았다. 컴퓨터 구조와 운영체제에 대한
www.hanbit.co.kr
해당 책을 읽고 나름대로 정리한 글입니다.
개요
쓰레드의 실행순서를 동기화하는 방법에 대해 알아보자.
생산자 소비자 문제
https://en.wikipedia.org/wiki/Producer%E2%80%93consumer_problem
Producer–consumer problem - Wikipedia
From Wikipedia, the free encyclopedia Family of computing problems In computing, the producer-consumer problem (also known as the bounded-buffer problem) is a family of problems described by Edsger W. Dijkstra since 1965. Dijkstra found the solution for th
en.wikipedia.org
생산자 소비자 문제는 동기화 방법을 설명하는 고전적인 문제이다.
생산자는 자원을 생산해 버퍼에 추가하고 소비자는 버퍼에 자원이 있다면 이를 소비한다.
문제는 만약에 버퍼가 가득차 생산자가 더 이상 자원을 넣을 공간이 없을 때,
버퍼가 비어있어 소비자가 자원을 획득할 수 없을 때 어떻게 해결할지이다.
기본적으로는 아래와 같은 방법들이 있다.
1. Sleep
2. Busy Waiting
3. Event
4. Semaphore
이번에는 Event에 대해서 알아보자.
Event기반 동기화
실행 순서 제어를 위한 가장 일반적인 오브젝트가 Event 오브젝트이다.
https://learn.microsoft.com/ko-kr/windows/win32/api/synchapi/nf-synchapi-createeventa
CreateEventA 함수(synchapi.h) - Win32 apps
명명되거나 명명되지 않은 이벤트 개체를 만들거나 엽니다. (ANSI)
learn.microsoft.com
HANDLE CreateEventA(
[in, optional] LPSECURITY_ATTRIBUTES lpEventAttributes,
[in] BOOL bManualReset,
[in] BOOL bInitialState,
[in, optional] LPCSTR lpName
);
bManualRest이 TRUE인 경우 Manual-Reset모드, FALSE인 경우 Auto-Reset모드이다.
Event의 경우 SetEvent를 통해서 오브젝트를 Signaled로 바꾼다.
이 때 Auto-Reset이라면 대기중인 쓰레드 하나를 깨우고 자동으로 non-signaled상태가 되며,
Manual-Reset이라면, ResetEvent를 호출하기 전 까지 여러 쓰레드가 깨어나게 된다.
따라서 여러 쓰레드를 동시에 깨워야 한다면 Manual-Reset을 사용할 수 있다.
다만 쓰레드가 깨어나는 순서를 알기는 어렵다.(스케줄링을 정확히 예측하기는 어려움)
타이머 기반 동기화
https://learn.microsoft.com/ko-kr/windows/win32/api/synchapi/nf-synchapi-createwaitabletimerw
CreateWaitableTimerW 함수(synchapi.h) - Win32 apps
대기 가능한 타이머 개체를 만들거나 엽니다.
learn.microsoft.com
Waitable Timer는 생성 시 Non-Signaled 상태이며 주어진 시간이 지나면 Signaled 상태로 바뀐다.
lpTimerAttributes 인자를 통해 Manual, Auto Reset모드를 선택할 수 있다.
https://learn.microsoft.com/ko-kr/windows/win32/api/winuser/nf-winuser-settimer
SetTimer 함수(winuser.h) - Win32 apps
지정된 시간 제한 값을 사용하여 타이머를 만듭니다.
learn.microsoft.com
그리고 SetTimer함수를 사용해 타이머를 설정할 수 있다.
이 때 pDueTime은 100nano단위로 설정하며, 양수일 때는 절대시간 음수일 때는 상대시간을 의미한다.
IPeriod를 설정하면 처음 실행된 이후 IPeriod 주기마다 반복하여 실행된다.