Thread를 이용하는 방법을 간단한 예제를 통해 정리한 문서 입니다. ¶
1) WaitForSingleObject ¶
/*************************************************************************************************************************
          * 2005.06.01. Hyo-Ki.
          *
          *  WINBASEAPI DWORD WINAPI WaitForSingleObject(HANDLE hHandle,  DWORD dwMilliseconds);
          *
          * 스레드는 위 함수를 사용하여 하나의 동기화 객체에 대해 대기 할 수 있다. 
          * 매개변수는 대개할 객체의 핸들과 타임아웃 값이다. 타임아웃으로 인해 대기가 풀리는 것을 원치 않으면
          * dwMilliseconds 값으로 INFINITE를 지정하면 된다. 이 함수는 리턴된 이유를 나타내는 값을 반환한다.
          * 이 함수는 동기화 객체가 신호를 받거나 동기화 객체가 폐기되거나 타임아웃이 될 때까지 스레드를 불록시킨다.
          *
          * WaitForSingleObject는 다음과 같은 반환 값을 갖는다.
          * - WAIT_OBJECT_0 : 지정된 객체가 신호를 받음
          * - WAIT_TIMEOUT   : 객체는 무신호 상태인데 타임아웃 시간이 종료됨
          * - WAIT_ABANDONED : 대기중인 뮤텍스 객체를 소유했던 스레드가 객체를 풀어주지 않고 종료
          * - WAIT_FAILED      : 지정된 동기화 객체의 핸들이 유효하지 않음
          *
          * 신호를 받았는지,  타임아웃 시간이 만료된 것인지 확인하기 위해서는 WaitForSingleObject가 
          * 반환한 코드를 살펴보아야 한다.
          *
          * Reference - Programming Microsoft Windows CE .NET
          *           - MSDN 참고
*************************************************************************************************************************/
void TVOutIntrProc(LPVOID pParam)
{
	HANDLE	hReadyEvent = (HANDLE)pParam;
	DWORD	dwTimeout, dwResult;
	if(!g_tvGlobal.hEvent)
		{
		RETAILMSG(1, (TEXT("<<TVOut>> Output event is not initialized.\n\r")));
		return;
		}
	SetEvent(hReadyEvent);	// Signal that thread is ready to get interrupt event
	dwTimeout = INFINITE;
    	while(1)
		{
		// WaitForSingleObject의 반환 코드 값 확인을 위한 변수 사용
		dwResult = WaitForSingleObject(g_tvGlobal.hEvent, dwTimeout);
		switch(dwResult)
			{
			case WAIT_OBJECT_0:		// Start Event
				if(!g_tvGlobal.bRunning)
					{
					dwTimeout = INFINITE;
					break;
					}
				lc822971_transfer();
				dwTimeout = TVOUT_OUTPUT_INTERVAL;
				break;
			case WAIT_TIMEOUT:
				if(!g_tvGlobal.bRunning)
					{
					dwTimeout = INFINITE;
					break;
					}
				
				lc822971_transfer();
				break;
			}
		}
}
2) WaitForMultipleObjects ¶
/***************************************************************************************************************************
* 2005.06.01. Hyo-Ki
* [ WinCE 에서 WaitForMultipleObjects 사용하기 ]
*
* WINBASEAPI DWORD WINAPI WaitForMultipleObjects(DWORD cObjects, CONST HANDLE *lphObjects, BOOL fWaitAll, DWORD dwTimeout);
*
* Thread는 여러 이벤트에 대해 대기할 수도 있다. 이 대기는 이벤트 가운데 어느 하나라도 신호를  받으면 끝난다. 
* 처음 두 매개변수는 대기할 이벤트 또는 뮤텍스의 개수 그리고 이벤트들의 배열을 가리키는 포인터이다. bWaitAll 매개변수는 
* 지정된 이벤트 가운데 어느 하나라도 신호를 받으면 함수가 리턴함을 나타내는 FALSE 값을 설정해야 한다. 마지막 매개변수는
* 밀리초 단위의 타임아웃 값이다. INFINITE로 지정하면 타임아웃이 적용되지 않는다.
* Win CE에서 WaitForMultipleObjects는 배열의 모든 이벤트가 신호를 받을 때까지 대기하는 기능을 지원 안한다.
*
* 함수가 리턴된 이유를 나타내는 코드를 반환한다.
* 동기화 객체가 신호를 받았기 때문에 함수가 린턴된 경우, 반환 값은 WAIT_OBJECT_0에 lpHandles 매개변수로 
* 전달한 핸들 배열의 인덱스를 더한 값이 된다. 스레드 블록을 해제한 핸들을 반환 코드 값으로 사용하게 된다.
* - WAIT_OBJECT_0
* - WAIT_OBJECT_1
* - WAIT_OBJECT_2
*           .......
* - WAIT_TIMEOUT
* - WAIT_ABANDONED
* - WAIT_FAILED
*
* Reference - Programming Microsoft Windows CE .NET
*           - MSDN 참고
*******************************************************************************************************************************/
void JackIntrProc(LPVOID pParam)
{
	HANDLE	hReadyEvent = (HANDLE)pParam;
	HANDLE	hJackEvent[2];
	DWORD	dwResult;
	hJackEvent[0] = CreateEvent(NULL, FALSE, FALSE, L"TVEnable");
	hJackEvent[1] = CreateEvent(NULL, FALSE, FALSE, L"TVDisable");
	SetEvent(hReadyEvent);	// Signal that thread is ready to get interrupt event
	while(1)
		{
		// WaitForMultipleObjects의 반환 코드 값 확인을 위한 변수를 사용
		dwResult = WaitForMultipleObjects(2, hJackEvent, FALSE, INFINITE);
		if(dwResult == WAIT_OBJECT_0)   // TVEnable event인 경우
			{
			if(g_tvGlobal.bRunning) // TV-Out이 현재 진행 중인 경우--> 특별한 작업 안함
				RETAILMSG(1, (TEXT("<<TV Out>> TV-Out is already running\n\r")));
			else    // TV-Out이 현재 수행되지 않는 경우--> 수행되도록 Open함수 호출
				TVO_Open(0, 0, 0);
			}
		else if(dwResult == WAIT_OBJECT_0 + 1)  // TVDisable event인 경우
			{
			if(g_tvGlobal.bRunning) // TV-Out이 현재 진행 중인 경우 --> 중지 시킴
				{
				TVO_Close(0);
				}
			else    // TV-Out이 현재 수행되지 않는 경우--> 특별한 작업 안함
				RETAILMSG(1, (TEXT("<<TV Out>> TV-Out is not running\n\r")));
			}
		}
}
3) 참고 할만한 사항들 ¶
1. 밤 사람의 프로젝트 공장 - 쓰레드(Thread)
http://www.bame.pe.kr/oldpf/ref/mfc/thread/thread.html
2. 동기화
http://www.synch3d.com/wiki/moin/moin.cgi/_b5_bf_b1_e2_c8_ad
3. RunTime: 프로세스와 쓰레드 동기화
http://www-128.ibm.com/developerworks/kr/linux/library/l-rt5/
4. RunTime: 프로세스와 쓰레드 관리하기
http://www-128.ibm.com/developerworks/kr/linux/library/l-rt7/
5. 오브젝트 동기화
http://www.oksystem.pe.kr/zboard/zboard.php?id=programmingc&no=57
6. 뮤텍스와 세마포어
http://blog.hanafos.com/blogView.asp?blogerid=vivitan&cateNo=35331&serialNo=2
http://www.bame.pe.kr/oldpf/ref/mfc/thread/thread.html2. 동기화
http://www.synch3d.com/wiki/moin/moin.cgi/_b5_bf_b1_e2_c8_ad3. RunTime: 프로세스와 쓰레드 동기화
http://www-128.ibm.com/developerworks/kr/linux/library/l-rt5/4. RunTime: 프로세스와 쓰레드 관리하기
http://www-128.ibm.com/developerworks/kr/linux/library/l-rt7/5. 오브젝트 동기화
http://www.oksystem.pe.kr/zboard/zboard.php?id=programmingc&no=576. 뮤텍스와 세마포어
http://blog.hanafos.com/blogView.asp?blogerid=vivitan&cateNo=35331&serialNo=2이상입니다. 혹시 필요하신 분들에게는 작은 도움이 되시길 바랍니다.
다분히 제 개인적인 목적으로 정리한 것이여서 내용이 많이 부족하오니
그점을 이해해 주시기 바랍니다. --coolbrain
다분히 제 개인적인 목적으로 정리한 것이여서 내용이 많이 부족하오니
그점을 이해해 주시기 바랍니다. --coolbrain
PS : 아직 분류를 어떻게 하는지 몰라서 분류는 정하지 않았습니다.
문서구조조정 을 잘하지 않으시면, 이 페이지는 자칫, ThisIsNotYourNotepad나 ThisIsNotAnEncyclopedia의 지적을 받기가 쉬워 보입니다. 노스모크에 대해서 좀 더 알아보시고, 노스모크의정체성, 노스모크에적절한주제도 한 번 참고해 보시고, 좋은 WikiGardening을 해주시기 바랍니다. -- gerecter
