윈도우즈 시스템 프로그래밍

윈도우즈 시스템 프로그래밍 14장 - 타이머 기반 동기화

111-000-111 2021. 8. 6. 16:40

 

 

 

윈도우즈 시스템 프로그래밍이라는 책과 해당 책의 저자이신 윤성우님의 강의를 통해 공부한 내용을 정리하는 글입니다.

 

 


 

 

 

타이머는 정해진 시간이 지나면 자동으로 Signaled 상태가 되는 특성이 있다. 타이머는 두 가지 형태로 구분지을 수 있다.

 

⦁ 수동 리셋 타이머 : 알람시계를 생각하면 된다. 6시에 알람을 맞춰놓으면 6시에 울리는 특성이다.

⦁ 주기적 타이머 : 수동 리셋 타이머에 주기적인 특성이 더해졌다. 6시에 알람을 맞추고 30분마다 한 번씩 주기적으로 알람이 울리도록 설정하는 기능이 있는 특성의 타이머다.

 

 

 

수동 리셋 타이머(Maual-Reset Timer)

 

⦁ 타이머 오브젝트는 정해진 시간이 지나면 Signaled 상태가 되는 커널 오브젝트이다.

 

⦁ 타이머 오브젝트를 생성하는 함수 CreateWaitableTimer

HANDLE CreateWaitableTimer (
    LPSECURITY_ATTRIBUTES lpTimerAttributes,
    BOOL bManualReset,
    LPCTSTR lpTimerName
);
//If the function fails, the return value is NULL.
⦁ lpTimerAttributes : 보안 속성 지정, 핸들을 상속하고자 할때 사용
⦁ bManualReset : 타이머 오브젝트를 수동 리셋(Manual-Reset)모드로 생성할지, 자동 리셋(Auto-Reset)모드로 생성할 것인지 결정
⦁ lpTimerName : 타이머 오브젝트의 이름 결정. NULL을 전달하면 이름 없는 타이머가 생성된다.

타이머 오브젝트는 무조건 Non-Signaled 상태로 생성된다.

 

 

⦁ 알람 시간 설정 함수 SetWaitableTimer

BOOL SetWaitableTimer (
    HANDLE hTimer,
    const LARGE_INTEGER* pDueTime,
    LONG lPeriod,
    PTIMERAPCROUTINE pfnCompletionRoutine,
    LPVOID lpArgToCompletionRoutine,
    BOOL fResume
);
// If the function fails, the return value is zero.
⦁ hTimer : 알람을 설정할 타이머의 핸들을 인자로 전달
⦁ pDueTime : 알람이 울리는 시간을 지정하기 위한 매개변수. +값이 전달되면 절대시간, -값이 전달되면 상대시간을 의미.
⦁ lPeriod : 주기적으로 알람을 울릴때 사용하는 인자. 0을 전달할 경우 사용하지 않는다는 의미이다.
⦁ fResume : 전원관리와 관련된 매개변수. 기본적으로 FALSE 전달

 

 

⦁ ManualResetTimer.cpp

#define _WIN32_WINNT 0x0400

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <process.h>

int _tmain(int argc, TCHAR* argv[])
{
	HANDLE hTimer = NULL;
	LARGE_INTEGER liDueTime;

	liDueTime.QuadPart = -100000000;

	hTimer = CreateWaitableTimer(NULL, FALSE, _T("WaitableTimer"));
	if (!hTimer)
	{
		_tprintf(_T("CreateWaitableTimer failed (%d) \n"), GetLastError());
		return 1;
	}

	_tprintf(_T("Waiting for 10 seconds ... \n"));

	SetWaitableTimer(hTimer, &liDueTime, 0, NULL, NULL, FALSE);

	WaitForSingleObject(hTimer, INFINITE);
	_tprintf(_T("Timer was signaled. \n"));
	MessageBeep(MB_ICONEXCLAMATION);
	
	return 0;
}

 

약 10초 뒤에 비프음이 들리는 프로그램이다.

 

 

⦁ PeriodicTimer.cpp

#define _WIN32_WINNT 0x0400

#include <stdio.h>
#include <tchar.h>
#include <windows.h>
#include <process.h>

int _tmain(int argc, TCHAR* argv[])
{
	HANDLE hTimer = NULL;
	LARGE_INTEGER liDueTime;

	liDueTime.QuadPart = -100000000;

	hTimer = CreateWaitableTimer(NULL, FALSE, _T("WaitableTimer"));
	if (!hTimer)
	{
		_tprintf(_T("CreateWaitableTimer failed (%d) \n"), GetLastError());
		return 1;
	}

	_tprintf(_T("Waiting for 10 seconds ... \n"));

	SetWaitableTimer(hTimer, &liDueTime, 5000, NULL, NULL, FALSE);

	while (1)
	{
		WaitForSingleObject(hTimer, INFINITE);
		_tprintf(_T("Timer was signaled. \n"));
		MessageBeep(MB_ICONEXCLAMATION);
	}

	return 0;
}

 

5초 간격으로 알람을 울려주는 프로그램이다.

 

중간에 타이머를 해제하고 싶으면 CancelWaitableTimer(인자로 핸들 전달)함수를 사용하면 된다. 이 함수는 자원을 반환하는 함수가 아닌, 가동중인 타이머를 중지시키는 역할을 한다. 자원 반환 및 소멸을 원할때는 CloseHandle 함수를 사용하면 된다.