2009년 01월 04일
WaitForMultipleObjects를 이용하여 특정 커널 오브젝트의 Signaled 상태 대기하기

WaitForMultipleObjects 함수의 경우 커널 오브젝트 핸들 배열에 대한 모든 핸들이 Signaled 상태가 될때 까지 대기 할 수도 있지만 특정 핸들이 Signaled 상태가 될 때 까지만 대기 할 수도 있습니다.

아래는 MSDN의 WaitForMultipleObjects 함수에 대한 내용 중 세번째 인자인 bWaitAll에 대한 설명입니다.


bWaitAll [in]

If this parameter is TRUE, the function returns when the state of all objects in the lpHandles array is signaled. If FALSE, the function returns when the state of any one of the objects is set to signaled. In the latter case, the return value indicates the object whose state caused the function to return.



이 인자를 TRUE로 했을 경우 이 함수는 lpHandles 인자로 넘어 온 배열의 모든 커널 오브젝트의 상태가 sigaled가 되었을 때 리턴한다고 합니다. 만약 FALSE로 했을 경우 이 함수는 특정 커널 오브젝트가 signaled 상태가 되었을 때 리턴 한다고 합니다. 그리고 이 리턴값은 이 함수를 리턴하게 한 커널 오브젝트를 가리킨다고 합니다. - 즉, 리턴값은 lpHandles 인자로 넘어 온 배열에서 signaled 상태가 된 커널 오브젝트의 인덱스 입니다. -

※ 어설픈 영어 실력으로 인해 오역이 있을 수 있습니다.


위 내용에 따라 예제 코드를 만들어 보았습니다. 두 개의 쓰레드를 실행 시키는데 이때 쓰레드의 인자값으로 각각의 쓰레드가 sleep할 시간을 전달하였습니다. 그리고 WaitMultipleObjects 함수에서 먼저 종료 된 쓰레드에 대해서 문자열을 출력하도록 하였습니다.


UINT WINAPI ThreadProc(LPVOID lpParam)
{
 DWORD* waitTime = (DWORD*) lpParam;
 
 Sleep(*waitTime);

 return 0;
}

int _tmain(int argc, _TCHAR* argv[])
{
 enum {THREAD_1, THREAD_2};
 HANDLE hArrThread[2];
 
 DWORD waitTime_1 = 3000;
 DWORD waitTime_2 = 1000;

 hArrThread[THREAD_1] = (HANDLE) _beginthreadex(NULL, 0, ThreadProc, (LPVOID) &waitTime_1, 0, NULL);
 hArrThread[THREAD_2] = (HANDLE) _beginthreadex(NULL, 0, ThreadProc, (LPVOID) &waitTime_2, 0, NULL);

 assert(NULL != hArrThread[THREAD_1] && NULL != hArrThread[THREAD_2]);

 //
 // WaiftForMultiPleObjects의 두번째 인자를 FALSE로 셋팅하면
 // 먼저 signal 상태로 전이 된 쓰레드의 핸들 배열 Index를 반환 한다.
 //
 switch(WaitForMultipleObjects(2, hArrThread, FALSE, INFINITE))
 {
 case THREAD_1:
  _tprintf(_T("The ended the THREAD_1.\n"));
  break;

 case THREAD_2:
  _tprintf(_T("The ended the THREAD_2.\n"));
  
  break;

 case WAIT_TIMEOUT:
 case WAIT_ABANDONED:
  return -1;
 }

 CloseHandle(hArrThread[THREAD_1]);
 CloseHandle(hArrThread[THREAD_2]);

 return 0;
}


* 실행 결과

THREAD_1은 3초를 대기 하고 THREAD_2는 1초를 대기 하기 때문에 THREAD_2에 대한 문자열이 출력 됩니다.

* 예제 프로젝트

WaitForMultiObjects.zip
 

by greenfrog | 2009/01/04 10:55 | C++ / WIN32 / MFC | 트랙백 | 덧글(1)
트랙백 주소 : http://greenfrog7.egloos.com/tb/1288479
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented by 곰돌맨 at 2012/12/12 15:03
오해의 소지가 있는 문구가 있어 지나가다 정정합니다.

수정본:
bWaitAll 인자가 FALSE 일 경우 파라메터 lpHandles 배열 중 signaled 상태가 된 한개 혹은 다수의 HANDLE 중 첫번째 HANDLE의 인덱스 값을 리턴합니다. 이 때 인덱스 범위는 (0 ~) 되겠습니다.

수정본 msdn 원문:
When bWaitAll is FALSE, this function checks the handles in the array in order starting with index 0, until one of the objects is signaled. If multiple objects become signaled, the function returns the index of the first handle in the array whose object was signaled.
(http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025(v=vs.85).aspx 에서 Remarks 섹션 확인 해보심 알 수 있습니다)

DWORD WINAPI WaitForMultipleObjects(
_In_ DWORD nCount,
_In_ const HANDLE *lpHandles,
_In_ BOOL bWaitAll,
_In_ DWORD dwMilliseconds
);

:         :

:

비공개 덧글



<< 이전 페이지 | 다음 페이지 >>