Thread

FrontPage|FindPage|TitleIndex|RecentChanges| UserPreferences P RSS

Thread를 이용하는 방법을 간단한 예제를 통해 정리한 문서 입니다.

자꾸 기억력이 나빠져 이렇게 글로 남기고자 해서 정리한 내용입니다.
주된 내용은 1) WaitForSingleObject 2) WaitForMultipleObjects 사용에 대한 것 위주 입니다. --coolbrain


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) 참고 할만한 사항들





이상입니다. 혹시 필요하신 분들에게는 작은 도움이 되시길 바랍니다.
다분히 제 개인적인 목적으로 정리한 것이여서 내용이 많이 부족하오니
그점을 이해해 주시기 바랍니다. --coolbrain


PS : 아직 분류를 어떻게 하는지 몰라서 분류는 정하지 않았습니다.

문서구조조정 을 잘하지 않으시면, 이 페이지는 자칫, ThisIsNotYourNotepadThisIsNotAnEncyclopedia의 지적을 받기가 쉬워 보입니다. 노스모크에 대해서 좀 더 알아보시고, 노스모크의정체성, 노스모크에적절한주제도 한 번 참고해 보시고, 좋은 WikiGardening을 해주시기 바랍니다. -- gerecter


"; if (isset($options[timer])) print $menu.$banner."
".$options[timer]->Write()."
"; else print $menu.$banner."
".$timer; ?> # # ?>