달력

52024  이전 다음

  • 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

Thread 의 종료를 기다리기 WaitForSingleObject 를 사용할때 주의할 사항이 있다.

 

[main]

SetEvent(exit_event);
DWORD waitResult;
waitResult = WaitForSingleObject(m_loadingThread, 20000);

[m_loadingThread]

while(true) {

    waitResult = WaitForSingleObject(exit_event, 20000);

    if (waitResult == WAIT_OBJECT_0) break;

    // Some Task that takes some time.

}

위의 코드를 보자. m_loadingThread 에는 exit_event 를 주면 Thread 가 종료되는 코드가 루프로 돌고 있고, main 에서는 exit_event 를 세팅하여 Thread 를 종료시키고자 한다. 하지만, 이 경우 문제점이 있다.

Thread 가 "Some Task" 를 실행중인 경우라면 WaitForSingleObject 문이 실행되는 시점에 Thread 가 살아있고, Thread 가 루프를 다시 돌아 break 를 만나 쓰레드가 종료되면 해피한 케이스로 모든 일이 종료될 것이다.

하지만, SetEvent 와 동시에 break 를 만난다면? SetEvent 와 동시에 쓰레드 루프에서 벗어나 쓰레드 함수가 종료될 것이고, WaitForSingleObject 는 이미 종료되어 버린 Thread 의 handle 을 무작정 기다리게 된다.

 

MSDN 에서는 "어떤 현상이 발생할지 알 수 없다." 고 경고하고 있다. (빨간색 부분)

(http://msdn.microsoft.com/en-us/library/ms687032(VS.85).aspx)

 

The WaitForSingleObject function returns when the specified object is in the signaled state or the time-out interval elapses.

To enter an alertable wait state, use the WaitForSingleObjectEx function. To wait for multiple objects, use the WaitForMultipleObjects.

DWORD WaitForSingleObject(
  HANDLE hHandle,
  DWORD dwMilliseconds
);

Parameters

hHandle
[in] Handle to the object. For a list of the object types whose handles can be specified, see the following Remarks section.

If this handle is closed while the wait is still pending, the function's behavior is undefined.

The handle must have the SYNCHRONIZE access right. For more information, see Standard Access Rights.

dwMilliseconds
[in] Time-out interval, in milliseconds. The function returns if the interval elapses, even if the object's state is nonsignaled. If dwMilliseconds is zero, the function tests the object's state and returns immediately. If dwMilliseconds is INFINITE, the function's time-out interval never elapses.

실제 테스트 결과, 대체로 Hangup 이 걸리는 현상이 발생하였다.

사용시 Thread 가 종료된 상태로 WaitForSingleObject 를 만나는 일이 없도록 주의해야 한다.

 

Thread 종료시 Sleep 을 이용하는 방법도 있겠지만 Sleep 을 쓰는 방법은 가급적 지양하는 것이 좋을 것이므로

그래서 아래와 같이 로직을 보완하였다. thread_state 를 두어 Thread가 종료되었는지 체크하도록 한다.

 

[main]

SetEvent(exit_event);
DWORD waitResult;

if (thread_state != MY_STATE_EXIT)
     waitResult = WaitForSingleObject(m_loadingThread, 20000);

[m_loadingThread]

thread_state = MY_STATE_RUNNING;

while(true) {

    waitResult = WaitForSingleObject(exit_event, 20000);

    if (waitResult == WAIT_OBJECT_0) break;

    // Some Task that takes some time.

}

thread_state = MY_STATE_EXIT


출처 : http://blog.naver.com/hankawiii?Redirect=Log&logNo=90084211565
Posted by 위너즈
|