API

프로세스, 스레드간의 상호 통신에 주의해야 될 점

디버그정 2011. 7. 21. 20:47

어떤 프로그램을 만들어서 타겟 프로그램을 조종한 적이 있는데,
이게 심심찮게 먹통이 되는 것이다.

이것저것 테스트해보니 타겟프로그램에 먹통이 생긴 경우
조종 프로그램도 같이 먹통이 되는 것이었다.
조사해보니 SendMessage와 같이 타겟프로그램에서 결과값을 보내 줄 때까지 대기하는 동기적인 함수가 문제였다.
타겟 프로그램이 먹통이 되버리니 처리가 안되어 결과값을 보내지 못하고
따라서 조종 프로그램도 계속 멍청히 대기하는 것이다.

그래서 결과값이 필요 없는 행동의 경우 PostMessage를 사용하고
(PostMessage는 타겟 윈도우를 소유한 스레드의 메시지 큐에 메시지를 넣고 바로 리턴한다.)
결과값이 필요한 경우는 SendMessageTimeout API를 사용하는 게 좋다.
이 함수는 일정시간동안 응답이 없으면 리턴하므로 조종 프로그램은 먹통을 피할 수 있다.

아래의 경우 타겟 프로그램의 리스트뷰에서 선택된 아이템의 갯수를 구하는 경우인데
이 경우는 반드시 리턴값이 필요한 경우라 하겠다.
SendMessageTimeout를 사용하여 아래와 같이 코딩할 수 있다.
앞의 4인수는 SendMessage와 같고 뒤의 3개는 각각 플래그, 대기시간, 결과값 포인터이다.

DWORD dwRet;
if (SendMessageTimeout(hList, LVM_GETSELECTEDCOUNT, 0, 0, SMTO_NORMAL, 1000, &dwRet))
{
// 성공한 경우 처리
cSelectedItems = dwRet;

}
else
{
// 실패한 경우 처리
dwErrorCode = GetLastError();
~~~
}