마이크로소프트 윈도우의 메시지 루프
마이크로소프트 윈도우 운영체제에서 메시지 루프(Message Loop)는 사용자 인터페이스(UI) 스레드가 시스템으로부터 전달받은 메시지를 처리하고, 해당 메시지를 적절한 윈도우 프로시저(window procedure)로 전달하는 기본 구조를 의미한다.
기본 개념
- 메시지(Message): 키보드 입력, 마우스 클릭, 타이머 이벤트, 시스템 요청 등과 같이 윈도우에게 전달되는 이벤트 단위이다.
- 메시지 큐(Message Queue): 각 UI 스레드마다 존재하며, 시스템이 생성한 메시지는 이 큐에 삽입된다.
- 메시지 루프: 스레드가 메시지 큐에서 메시지를 꺼내어 처리하는 반복적인 코드 블록이다.
핵심 API
| API | 설명 |
|---|---|
GetMessage |
메시지 큐에서 메시지를 꺼낸다. 큐가 비어 있으면 메시지가 도착할 때까지 블록한다. 반환값이 0이면 WM_QUIT 메시지를 의미한다. |
PeekMessage |
GetMessage와 유사하지만, 메시지가 없을 경우 즉시 반환한다. 비동기적 처리에 사용된다. |
TranslateMessage |
키보드 메시지를 문자 입력 메시지(WM_CHAR 등)로 변환한다. |
DispatchMessage |
현재 메시지를 해당 윈도우 프로시저에 전달한다. |
전형적인 메시지 루프 구현 예시(중요한 흐름만 기재):
MSG msg;
while (GetMessage(&msg, nullptr, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
주요 역할
- 이벤트 수신: 시스템이 생성한 모든 메시지를 큐에서 받아들인다.
- 전처리:
TranslateMessage를 통해 키보드 입력을 문자 메시지로 변환한다. - 분배:
DispatchMessage가 윈도우 프로시저(WndProc)에 메시지를 전달한다. - 루프 종료:
WM_QUIT메시지를 수신하면GetMessage가 0을 반환하고 루프가 종료된다.
변형 및 확장
- 모델-뷰-컨트롤러(MVC) 구조: 메시지 루프 내부에서 추가적인 작업(예: 타스크 처리, 렌더링)과 결합하기 위해
PeekMessage와MsgWaitForMultipleObjects등을 이용해 비동기 처리를 구현한다. - 멀티스레드 UI: 기본적으로 UI 스레드당 하나의 메시지 루프가 존재한다. 워커 스레드에서는 메시지 큐가 없으며, UI 업데이트는 반드시 UI 스레드의 메시지 루프를 통해 수행한다.
- 게임 및 실시간 애플리케이션: 고성능 요구 사항에 따라
PeekMessage를 사용해 루프를 비블로킹 형태로 구현하고, 프레임당 렌더링 로직을 직접 삽입한다.
관련 개념
- 윈도우 프로시저(WndProc): 메시지 루프에 의해 전달된 메시지를 실제로 처리하는 함수.
- 메시지 필터링:
GetMessage의wMsgFilterMin·wMsgFilterMax파라미터를 사용해 특정 범위의 메시지만 수신할 수 있다. - 핸들러(Handler): 메시지 종류에 따라 별도의 처리 로직을 구현하는 구조체나 클래스.
참고 사항
- 메시지 루프는 윈도우 기반 애플리케이션의 핵심 실행 흐름이며, 운영체제 수준에서 제공되는 API에 의해 표준화되어 있다.
- 메시지 루프 구현 방식은 애플리케이션의 종류(일반 GUI, 게임, 실시간 시뮬레이션 등)에 따라 다양하게 변형될 수 있다.
위 내용은 마이크로소프트가 제공하는 공식 문서와 일반적인 개발 자료에 근거한 객관적인 설명이다.