[MFC] 이벤트를 사용해보자 CreateEvent, SetEvent, ResetEvent
Visual Studio 2012 사용 이벤트를 사용해보자. 이벤트는 Event Object를 의미하며, 이 오브젝트를 활용하여 WaitForSingleObject(), WaitForMultipleObjects() 등의 함수에 Signaled, Nonsignaled 상태를 리턴..
zadd.tistory.com
Visual Studio 2012 사용
이벤트를 사용해보자.
이벤트는 Event Object를 의미하며, 이 오브젝트를 활용하여 WaitForSingleObject(), WaitForMultipleObjects() 등의 함수에 Signaled, Nonsignaled 상태를 리턴받아 처리하기위한 목적으로 사용한다. 스레드에서 사용된다.
1. 함수원형 살펴보기
(1) CreateEvent(): Event Object HANDLE을 생성한다.
1 2 3 4 5 6 |
HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPTSTR lpName ); |
파라미터:
IpEventAttributes - 무시, NULL값 입력하면 된다.
bManualReset - TRUE시에는 ResetEvent()을 활용해 Manual로 이벤트를 리셋 시켜야한다. FALSE시는 이벤트가 Signaled 상태가 되면 Single Waiting Thread 이후 자동으로 Nonsignaled 상태로 변한다.
bInitialState - 초기 이벤트 상태를 나타낸다. TRUE시 Signaled, FALSE시 Nonsignaled.
IpName - Event Object의 이름을 나타내는 포인터. 보통 NULL값을 사용한다.
(2) SetEvent(): 해당 Event Object의 상태를 Signaled 상태로 변환한다.
1 2 3 |
BOOL SetEvent( HANDLE hEvent ); |
파라미터:
hEvent - Event Object를 입력하면 된다.
(3) ResetEvent(): 해당 Event Object의 상태를 Nonsignaled 상태로 변환한다.
1 2 3 |
BOOL ResetEvent( HANDLE hEvent ); |
파라미터:
hEvent - Event Object를 입력하면 된다.
(4) WaitForSingleObject(): 스레드에서 해당 Event Object의 상태를 불러올 때 사용한다. Event말고도 Thread 핸들이나 다른 Object의 상태를 볼 때도 사용된다.
1 2 3 4 |
DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ); |
파라미터:
hHandle - Event Object를 입력하면 된다.
dwMilliseconds - Time Out 관련 변수이다. INFINITE가 입력되면 해당 Event Object가 Signaled가 될 때까지 계속 기다린다. 숫자가 입력되면 해당 숫자의 시간만큼(ms기준) 기다린 후, WAIT_TIMEOUT을 리턴한다.
2. 선언
테스트를 위해 ThreadTest란 이름의 MFC 대화상자 프로젝트를 생성했다.
ThreadTestDlg.h
1 2 3 4 5 6 7 8 9 |
// CThreadTestDlg 대화 상자 class CThreadTestDlg : public CDialogEx { //... public: HANDLE g_hEvent; static UINT MyThread(LPVOID lParam); CWinThread *m_pThread; }; |
Event Object를 적용할 HANDLE(g_hEvent)과, 스레드로 활용할 MyThread를 선언하였다.
3. 정의
ThreadTestDlg.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
BOOL CThreadTestDlg::OnInitDialog() { //...
g_hEvent = CreateEvent(NULL,TRUE,FALSE,NULL); m_pThread = AfxBeginThread(MyThread,this);
return TRUE; // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다. }
UINT CThreadTestDlg::MyThread(LPVOID lParam) { CThreadTestDlg *g_pDlg = (CThreadTestDlg*)lParam; UINT ret;
HANDLE pEvent = (g_pDlg->g_hEvent);
while(TRUE) { ret = WaitForSingleObject(pEvent,INFINITE);
if(ret==WAIT_FAILED) //HANDLE이 Invalid 할 경우 { return 0; } else if(ret==WAIT_TIMEOUT) //TIMEOUT시 명령 { continue; } else { //Event Object: Signaled 상태 //프로그램 코드 ResetEvent(pEvent); //Event Object Nonsignaled 상태로 변환 } } return ret; } |
(1) OnInitDialog() 함수에서 EventObject와 스레드를 정의한다.
(2) 스레드에서는 Event Object Handle을 넘겨 받고 WaitForSingleObject()를 활용하여 Event 상태를 받는다.
*여기서는 INFINITE를 사용하여 Signaled 상태를 받을 때까지 대기한다.
(3) Signaled 상태일 시 "//프로그램 코드"를 실행 한후 ResetEvent() 함수로 상태를 Nonsignaled 상태로 변환한다. 이렇게 되면 스레드는 다시 WaitForSingleObject()로 넘어가서 대기한다.
4. 테스트
버튼 하나 만들어서 SetEvent(g_hEvent); 를 사용하여 Event Object를 Signaled 상태로 만들어 테스트해보자.
끝