티스토리 뷰
API 메시지 루프
프로그램을 비 스레드로 무한루프(while(1)) 로 만들면 프로그램이 멈추지만, 메시지 루프는 WM_QUIT 메시지를 받을때까지 무한 루프로 동작하는데 왜 멈추지 않는지 이유를 몰랐다. 그냥 막연히 스레드로 동작하는가 보다 생각했는데 그게 아니다.
1
2
3
4
5
6
7
8 |
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} |
cs |
메시지가 발생하면 OS(윈도우즈)는 시스템 메시지큐에 저장하고 다시 각 응용 프로그램의 메시지 큐로 이동하게된다.
GetMessage() 는 응용프로그램의 메시지 큐에 메시지가 있으면 가져오고, 메시지가 없으면 반환하지 않고 아무 작업도 하지 않는 idle 상태가 된다. OS는 이때 쉬는 시간의 CPU를 다른 프로그램에게 할당한다.
(참고, 메시지큐에 메시지가 없으면 GetMessage()는 리턴하지 않고 OS가 다른 프로세스에게 프로세서를 할당하게 되어 idle 상태(무한대기)가 된다. 메시지가 큐에 들어오면 GetMessage() 가 리턴한다. - 멀티태스킹
결국 GeMessage()는 1. 메시지가져오기 2. 대기한다 3. 양보한다 3가지 특성을 가진다. http://blog.naver.com/wlsgh31/70188390166)
해당 프로그램의 메뉴를 클릭하던지 어떤 이벤트가 발생하면 idle 상태에서 깨워 해당 메시지를 가져와 메시지를 처리게된다.
위에 메시지 루프 기본 코드로 실행하고 작업관리자를 보면
위 코드를 아래와 같이 무한 루프로 수정해서 실행하면 프로그램 동작은 차이가 없다.
1
2
3
4
5
6
7
8
9
10 |
while (1)
{
if (GetMessage(&msg, nullptr, 0, 0) == WM_QUIT)
break;
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
} |
cs |
그림1과 그림2 비교해 보면 둘다 CPU 사용률은 0%에 가깝다.