Sleep()함수를 일정시간 이상 사용하다 보면 Sleep 하는 동안 프로그램이 CPU를 사용하지 않기 때문에 그 프로그램이 응답없음으로 나오는 경우가 있다. 만약 1초에 Progress바를 한칸씩 생성한다고 할 경우에 프로그램이 응답없음이 되어버리면 중간에 Progress바가 멈춰있다가 Sleep함수에서 설정한 시간이 다 된후에 갑자기 완료가 된다.
그럼 이 문제를 어떻게 해결해야 할까???
먼저 제일 처음 쓰레드와 동기화를 생각해 볼수 있다.
쓰레드로 일정시간 돌리는 동안 메인 쓰레드는 WaitForSingleObject()함수로 기다리게 한다고 가정해보자.
이럴 경우에 메인 쓰레드는 효율적 사용을 위해서 다른 쓰레드에게 CPU 사용권을 넘겨준다. 결국 Sleep과 똑같은 상태로 일정 시간이 지날 경우에는 응답없음이 뜰수 밖에 없다.
그렇다면 응답없음이 나오지 않게 즉, CPU를 계속 점유하고 있을 방법은 뭐가 있을까?
void Delay_Wait(DWORD dwMillisecond)
{
MSG msg;
DWORD dwStart;
dwStart = GetTickCount();
while(GetTickCount() - dwStart < dwMillisecond)
{
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
위와 같은 함수를 만든후 Sleep 함수를 사용한것과 같이 사용할 경우에 응답없음을 해결할수 있다.
위의 함수의 로직을 보게 되면 GetTickCount로 시간을 세서 그 시간 전까지 메세지 루프를 돌다가 설정한 시간보다 같거나 클 경우 while 구문을 빠져나오게 된다.
PeekMessage는 WinMain에서 자주쓰이는 GetMessage와는 달리 (GetMessage는 메세지가 들어올때까지 기다린다.) 메세지 큐에 메세지가 있는지 없는지 확인 후 바로 리턴한다. 그걸 while로 계속 해서 메세지 큐를 검사하기 때문에 시간을 기다리는 동안에도 CPU를 계속해서 사용할 수 밖에 없다. 그러므로 응답없음에 빠지지 않고 프로그램은 정상적으로 실행되게 된다.
추가로 위에서 사용한 PeekMessage 에서 PM_REMOVE인자는 메세지 큐에서 메세지를 가지고 오고나서 메세지 큐에서 메세지를 제거해 준다는 뜻으로 사용한 메세지는 사용후 메세지 큐에서 제거해 주는게 바람직 하다.
PeekMessage의 자세한 사항은 http://msdn.microsoft.com/ko-kr/library/ms911928(en-us).aspx 여기서 확인하기 바란다.
참조문헌: http://lafirr.tistory.com/56
'Computer > Windows Programming' 카테고리의 다른 글
| Sleep함수 대신 사용할수 있는 함수 만들기 (0) | 2012/04/22 |
|---|