2008. 10. 1. 18:02

Windows API 메시지 데드록(DeadLock) 관련 함수


'SendMessage()'라는 함수를 통해서 프로그래머는 일종의 사용자 메시지를만들 수 있다.
같은 스레드 내에서 이 함수를 사용할 경우에는 크게 문제 될 것이 없지만, 다른 스레드로 SendMessage()를 사용해 메시지를 날리게 될 경우 상당히 좋지않은 결과를 초래할 수도 있다.

SendMessage() 함수는 메시지를 받은 윈도우 프로시저가 리턴하기 전까지는 리턴하지 않기 때문에, 다른 스레드로 메시지를 날리게 될 경우 그 스레드에서 리턴하지 않는 한 SendMessage()를 한 스레드는 홀드되는 상태로 남게 된다. '데드록(DeadLock)'가 되는 것이다.

이를 해결하는 방법으로 여러가지가 있겠지만, 간단히 몇가지를 살펴보면 다음과 같다.
'InSendMessage()''ReplyMessage()'를 이용하여 SendMessage()로 부터 받은 메시지를 처리하는 부분이다.
if(InSendMessage())             // 다른 스레드로부터 메시지가 들어왔는지 확인
    ReplyMessage(TRUE);      // SendMessage() 로부터 전달된 메시지를 바로 리턴한다.

위와 같은 처리를 해주면, SendMessage()를 호출한 윈도우는 리턴되지 않더라도 즉시 다른 일을 할 수 있다.

다른 방법으로는 SendMessage()를 이용하지 않고 다음의 함수를 사용하는 방법이다.
BOOL SendNotifyMessage(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam );
LRESULT SendMessageTimeout( HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam,              
                                                UINT fuFlags, UINT uTimeout, PDWORD_PTR lpdwResult );

'SendNotifyMessage()' 함수는 SendMessage()와 유사하지만, hWnd 가 다른 스레드의 윈도우일 경우 대기를 하지 않고 즉시 리턴하는 함수이다.
'SendMessageTimeout()' 함수는 지정한 시간이 지나면 메시지의 처리 여부와 상관없이 즉시 리턴함으로 메시지를 보낸 윈도우가 홀드되는 것을 막는다.