#include <window.h>
#include <stdio.h>
#include <process.h>
// main thread 와 child thread 사이에 공유되는 이벤트 핸들
// 을 저장하기 위한 전역 변수
HANDLE g_hAutoResetEvent = NULL;
HANDLE g_hManualResetEvent = NULL;
unsigned __stdcall ThreadStartFunc(void* lpThreadParameterId)
{
DWORD dwStatus;
// 스레드 시작을 알린다.
printf("Thread #%d id=0x%08x, started.\n",
(int) lpThreadParameterId,
GetCurrentThreadId());
// auto reset event 대기
printf("Thread #%d id=0x%08x, waiting for auto-reset event.\n",
(int) lpThreadParameterId,
GetCurrentThreadId());
dwStatus = WaitForSingleObject(g_hAutoResetEvent, INFINITE);
if (dwStatus == WAIT_OBJECT_0)
{
printf("Thread #%d id=0x%08x, wait for auto-reset event succeeded.\n",
(int) lpThreadParameterId,
GetCurrentTrheadId());
}
else
{
printf("Thread #%d id=0x%08x, wait for auto-reset event failed.\n",
(int) lpThreadParameterId,
GetCurrentThreadId());
return 1;
}
printf("Thread #%d id=0x%08x, waiting for manual-reset event. \n",
(int) lpThreadParameterId,
GetCurrentThreadId());
dwStatus = WaitForSingleObject(g_hManualResetEvent, INFINITE);
if (dwStatus == WAIT_OBJECT_0)
{
printf("Thread #%d id=0x%08x, wait for manual-reset event succeeded.\n",
(int) lpThreadParameterId,
GetCurrentThreadId());
}
else
{
printf("Thread #%d id=0x%08x, wait for auto-reset event failed.\n",
(int) lpThreadParameterId,
GetCurrentThreadId());
return 2;
}
// 종료한다.
printf("Thread #%d id=0x%08x, exiting. \n",
(int) lpThreadParameterId,
GetCurrentThreadId());
return 0;
}
int main(void)
{
DWORD dwStatus;
BOOL bStatus;
HANDLE ahThreads[2];
DWORD dwThreadID1;
DWORD dwThreadID2;
// 자동 리셋 이벤트를 생성한다.
g_hAutoResetEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hAutoResetEvent)
{
printf("Primary thread created auto-reset event.\n");
}
else
{
printf("Primary thread unable to create auto-reset event.\n");
exit(-1);
}
// 수동 리셋 이벤트를 생성한다.
g_hManualResetEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_hAutoResetEvent)
{
printf("Primary thread created manual-reset event.\n");
}
else
{
printf("Primary thread unable to craete manual-reset event.\n");
exit(-2);
}
// 첫째 자식 스레드 생성
ahThreads[0] = (HANDLE) _beginthreadex(NULL, 0, ThreadStartFunc, (void*)1, 0, (unsigned*)&dwThreadID1);
if (ahThread[0])
{
printf("Primary thread created child thread #1 with id=0x%08x.\n", dwThreadID1);
}
else
{
printf("Primary thread unable to create child thread #1.\n");
exit(-3);
}
// 둘째 자식 스레드를 생성
ahThreads[1] = (HANDLE) _beginthreadex(NULL, 0, ThreadStartFunc, (void*)2, 0, (unsigned*)&dwThreadID2);
if (ahThread[1])
{
printf("Primary thread created child thread #2 with id=0x%08x.\n", dwThreadID2);
}
else
{
printf("Primary thread unable to create child thread #2.\n");
exit(-4);
}
// 이벤트를 시그널하기 전에 자식 스레드가 수행을 시작하도록 한다.
// 프로그램이 제대로 동작하는 데에는 전혀 상관이 없지만, 이렇게 코드를
// 구성함으로써 둘째 스레드에게 자동 리셋 이벤트를 처음으로 시그널링할
// 수 있는 동일한 기회를 줄 수 있다.
Sleep(1000);
// 자동 리셋 이벤트를 시그널한다.
printf("Primary thread signaling auto-reset event. \n");
bStatus = SetEvent(g_hAutoResetEvent);
if (!bStatus)
{
printf("Unable to signal auto-reset event.\n");
exit(-5);
}
// 수동 리셋 이벤트를 시그널링
printf("Primary thread signaling manual-reset event.\n");
bStatus = SetEvent(g_hManualResetEvent);
if (!bStatus)
{
printf("Unable to signal manual-reset event.\n");
exit(-6);
}
else
// 자식 스레드 하나가 종료할 때까지 대기한다.
printf("Primary thread waiting for one of thre chlid threads to exit. \n");
dwStatus = WaitForMultipleObjects(2, ahThreads, FALSE, INFINITE);
if ((dwStatus == WAIT_OBJECT_S) || (dwStatus == WAIT_OBJECT_0 + 1))
{
printf("Wait for one child thread to exit succeded.\n");
}
else
{
printf("Wait for one child thread to exit failed.\n");
exit(-7);
}
// 자동 리셋 이벤트를 다시 시그널링 한다.
printf("Primary thread signaling auto-reset event again\n");
bStatus = SetEvent(g_hAutoResetEvent);
if (!bStatus)
{
printf("Unable to signal auto-reset event again\n");
exit(-8);
}
// 스레드 두 개가 모두 종료될 때까지 대기
printf("Primary thread waiting for both child threads to exit.\n");
dwStatus = WaitForMultipleObjects(2, ahThreads, TRUE, INFINITE);
if (dwStatus == WAIT_OBJECT_0)
{
printf("Wait for both child threads to exit succeded. \n");
}
else
{
printf("Wait for both child threads to exit failed.\n");
exit(-9);
}
// 정리 작업
CloseHandle(ahThread[0]);
CloseHandle(ahThread[1]);
CloseHandle(g_hAutoResetEvent);
CloseHandle(g_hManualResetEvent);
// 종료
printf("Primary thread exiting. \n");
return 0;
}
[code]result
Primary thread created auto-reset event.
Primary thread created manual-reset event.
Primary thread created child thread #1 with id=0xfffabeeb.
Primary thread created child thread #2 with id=0xfffab883.
Thread #1 id=0xfffabeeb, started.
Thread #1 id=0xfffabeeb, waiting for auto-reset event.
Thread #2 id=0xfffab883, started.
Thread #2 id=0xfffab883, waiting for auto-reset event.
Primary thread signaling auto-reset event.
Primary thread signaling manual-reset event.
Primary thread waiting for one of thre chlid threads to exit.
Thread #1 id=0xfffabeeb, waiting for auto-reset event succeeded.
Thread #1 id=0xfffabeeb, waiting for manual-reset event succeeded.
Thread #1 id=0xfffabeeb, exiting.
Wait for one child thread to exit succeeded.
Primary thread signaling auto-reset event succeeded.
Primary thread waiting for both child threads to exit.
Thread #2 id=0xfffab883, waiting for auto-reset event succeeded.
Thread #2 id=0xfffab883, waiting for manual-reset event succeeded.
Thread #2 id=0xfffab883, waiting for auto-reset event succeeded.
Thread #2 id=0xfffab883, exiting.
Wait for both child threads to exit succeeded. Primary thread exiting.
[/code]
#include <stdio.h>
#include <process.h>
// main thread 와 child thread 사이에 공유되는 이벤트 핸들
// 을 저장하기 위한 전역 변수
HANDLE g_hAutoResetEvent = NULL;
HANDLE g_hManualResetEvent = NULL;
unsigned __stdcall ThreadStartFunc(void* lpThreadParameterId)
{
DWORD dwStatus;
// 스레드 시작을 알린다.
printf("Thread #%d id=0x%08x, started.\n",
(int) lpThreadParameterId,
GetCurrentThreadId());
// auto reset event 대기
printf("Thread #%d id=0x%08x, waiting for auto-reset event.\n",
(int) lpThreadParameterId,
GetCurrentThreadId());
dwStatus = WaitForSingleObject(g_hAutoResetEvent, INFINITE);
if (dwStatus == WAIT_OBJECT_0)
{
printf("Thread #%d id=0x%08x, wait for auto-reset event succeeded.\n",
(int) lpThreadParameterId,
GetCurrentTrheadId());
}
else
{
printf("Thread #%d id=0x%08x, wait for auto-reset event failed.\n",
(int) lpThreadParameterId,
GetCurrentThreadId());
return 1;
}
printf("Thread #%d id=0x%08x, waiting for manual-reset event. \n",
(int) lpThreadParameterId,
GetCurrentThreadId());
dwStatus = WaitForSingleObject(g_hManualResetEvent, INFINITE);
if (dwStatus == WAIT_OBJECT_0)
{
printf("Thread #%d id=0x%08x, wait for manual-reset event succeeded.\n",
(int) lpThreadParameterId,
GetCurrentThreadId());
}
else
{
printf("Thread #%d id=0x%08x, wait for auto-reset event failed.\n",
(int) lpThreadParameterId,
GetCurrentThreadId());
return 2;
}
// 종료한다.
printf("Thread #%d id=0x%08x, exiting. \n",
(int) lpThreadParameterId,
GetCurrentThreadId());
return 0;
}
int main(void)
{
DWORD dwStatus;
BOOL bStatus;
HANDLE ahThreads[2];
DWORD dwThreadID1;
DWORD dwThreadID2;
// 자동 리셋 이벤트를 생성한다.
g_hAutoResetEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if (g_hAutoResetEvent)
{
printf("Primary thread created auto-reset event.\n");
}
else
{
printf("Primary thread unable to create auto-reset event.\n");
exit(-1);
}
// 수동 리셋 이벤트를 생성한다.
g_hManualResetEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_hAutoResetEvent)
{
printf("Primary thread created manual-reset event.\n");
}
else
{
printf("Primary thread unable to craete manual-reset event.\n");
exit(-2);
}
// 첫째 자식 스레드 생성
ahThreads[0] = (HANDLE) _beginthreadex(NULL, 0, ThreadStartFunc, (void*)1, 0, (unsigned*)&dwThreadID1);
if (ahThread[0])
{
printf("Primary thread created child thread #1 with id=0x%08x.\n", dwThreadID1);
}
else
{
printf("Primary thread unable to create child thread #1.\n");
exit(-3);
}
// 둘째 자식 스레드를 생성
ahThreads[1] = (HANDLE) _beginthreadex(NULL, 0, ThreadStartFunc, (void*)2, 0, (unsigned*)&dwThreadID2);
if (ahThread[1])
{
printf("Primary thread created child thread #2 with id=0x%08x.\n", dwThreadID2);
}
else
{
printf("Primary thread unable to create child thread #2.\n");
exit(-4);
}
// 이벤트를 시그널하기 전에 자식 스레드가 수행을 시작하도록 한다.
// 프로그램이 제대로 동작하는 데에는 전혀 상관이 없지만, 이렇게 코드를
// 구성함으로써 둘째 스레드에게 자동 리셋 이벤트를 처음으로 시그널링할
// 수 있는 동일한 기회를 줄 수 있다.
Sleep(1000);
// 자동 리셋 이벤트를 시그널한다.
printf("Primary thread signaling auto-reset event. \n");
bStatus = SetEvent(g_hAutoResetEvent);
if (!bStatus)
{
printf("Unable to signal auto-reset event.\n");
exit(-5);
}
// 수동 리셋 이벤트를 시그널링
printf("Primary thread signaling manual-reset event.\n");
bStatus = SetEvent(g_hManualResetEvent);
if (!bStatus)
{
printf("Unable to signal manual-reset event.\n");
exit(-6);
}
else
// 자식 스레드 하나가 종료할 때까지 대기한다.
printf("Primary thread waiting for one of thre chlid threads to exit. \n");
dwStatus = WaitForMultipleObjects(2, ahThreads, FALSE, INFINITE);
if ((dwStatus == WAIT_OBJECT_S) || (dwStatus == WAIT_OBJECT_0 + 1))
{
printf("Wait for one child thread to exit succeded.\n");
}
else
{
printf("Wait for one child thread to exit failed.\n");
exit(-7);
}
// 자동 리셋 이벤트를 다시 시그널링 한다.
printf("Primary thread signaling auto-reset event again\n");
bStatus = SetEvent(g_hAutoResetEvent);
if (!bStatus)
{
printf("Unable to signal auto-reset event again\n");
exit(-8);
}
// 스레드 두 개가 모두 종료될 때까지 대기
printf("Primary thread waiting for both child threads to exit.\n");
dwStatus = WaitForMultipleObjects(2, ahThreads, TRUE, INFINITE);
if (dwStatus == WAIT_OBJECT_0)
{
printf("Wait for both child threads to exit succeded. \n");
}
else
{
printf("Wait for both child threads to exit failed.\n");
exit(-9);
}
// 정리 작업
CloseHandle(ahThread[0]);
CloseHandle(ahThread[1]);
CloseHandle(g_hAutoResetEvent);
CloseHandle(g_hManualResetEvent);
// 종료
printf("Primary thread exiting. \n");
return 0;
}
[code]result
Primary thread created auto-reset event.
Primary thread created manual-reset event.
Primary thread created child thread #1 with id=0xfffabeeb.
Primary thread created child thread #2 with id=0xfffab883.
Thread #1 id=0xfffabeeb, started.
Thread #1 id=0xfffabeeb, waiting for auto-reset event.
Thread #2 id=0xfffab883, started.
Thread #2 id=0xfffab883, waiting for auto-reset event.
Primary thread signaling auto-reset event.
Primary thread signaling manual-reset event.
Primary thread waiting for one of thre chlid threads to exit.
Thread #1 id=0xfffabeeb, waiting for auto-reset event succeeded.
Thread #1 id=0xfffabeeb, waiting for manual-reset event succeeded.
Thread #1 id=0xfffabeeb, exiting.
Wait for one child thread to exit succeeded.
Primary thread signaling auto-reset event succeeded.
Primary thread waiting for both child threads to exit.
Thread #2 id=0xfffab883, waiting for auto-reset event succeeded.
Thread #2 id=0xfffab883, waiting for manual-reset event succeeded.
Thread #2 id=0xfffab883, waiting for auto-reset event succeeded.
Thread #2 id=0xfffab883, exiting.
Wait for both child threads to exit succeeded. Primary thread exiting.
[/code]
'Windows > MFC' 카테고리의 다른 글
MainFrame 타이틀바 없애기, 프레임없애기 (0) | 2013.10.02 |
---|---|
[GDI+] Font 에 Anti-aliasing (안티 알라이싱) 주기 (0) | 2013.10.02 |
[thread] 세마포어를 이용한 스레드 동기화 (0) | 2013.10.02 |
Mutex를 이용한 스레드 동기화 (0) | 2013.10.02 |
WaitForSingleObject 함수 와 WaitForMultipleObject 함수 (0) | 2013.10.02 |