2012-01-13 2 views
1

Windows 메시지를 처리 ​​할 두 개의 스레드가 필요합니다. 클라이언트 영역에서 키/마우스 입력을위한 하나 (이 스레드는 또한 게임 로직을 처리합니다.) 게임을 만들고 일부 메시지가 DefWindowProc()을 차단하여 게임을 멈추게하기 때문에 나머지 하나는 나머지를위한 것입니다.Windows : 메시지를 처리하는 두 개의 스레드가 있습니까?

어떻게하면됩니까?

+0

DefWindowProc는 실제로 "차단"하지 않습니다 ... 꽤 빠릅니다. 차단을 야기하는 예제 메시지를 줄 수 있습니까? –

+0

기존 디자인을 그대로 유지하고 대신 배경 스레드에서 느린 응답을 실행하여 게임이 멈추지 않도록하는 것이 좋습니다. –

+0

DefWindowProc은 윈도우를 움직이거나 크기를 조정할 때 마우스 버튼을 놓을 때까지 차단합니다. – Jonathan

답변

3

코디가 작성한 것과는 반대로, 당신은 가장 확실하게 여러 스레드의 메시지를 처리 ​​할 수 ​​있습니다. 그러나 이것은 사용자 정의가 가능한 모든 것이 아닙니다. 오히려, 창은 스레드 선호도가 있습니다. 각 스레드는 해당 스레드가 작성한 창에 보내거나 게시 한 메시지를 수신합니다. 창 메시지를 다른 스레드로 전달할 방법이 없습니다.

특정 상황에서 숨겨진 창과 메시지 루프가있는 작업자 스레드를 만들지 않습니까? 주 창에서 주 스레드에서 처리하고 싶지 않은 메시지를 받으면 다른 창에 게시하고 대기열에 넣고 작업자 스레드에서 처리합니다.

+0

아, 나는 다른 것을 암시하려는 것이 아닙니다. 아마 나는 그것을 조금 과장했다. 너무 많은 사람들이 비 UI 스레드에서 UI 작업을 시도하는 데 큰 어려움을 겪는 것을 보았습니다. –

+0

정확하게 필요한 부분 – Jonathan

1

Windows가 이미 제공하는 메시지 대기열을 처리하는 단일 스레드 만 있으면됩니다. 계산적으로 무거운 작업을 수행하는 경우 CreateThread를 사용하여 새 스레드를 만들어 별도의 스레드로 보내야합니다. 당신이 당신이 끊임없이 이것을하는 것을 알게된다면, 거기에 그 스레드를 영구적으로 가지고 있어야하지만, 필요할 때 작업하라는 신호를 보내십시오.

1

아니요, 모든 메시지를 단일 스레드에서 처리해야합니다. 이 단일 스레드는 사용자 인터페이스를 제어하는 ​​스레드이므로 UI ​​스레드라고도합니다. UI가 아닌 스레드에서 UI 메시지를 처리하려고하면 문제가 발생할 수 있습니다.

그러나 일반적인 문제는 특정 메시지에 대한 응답으로 오래 실행되고 계산 집약적 인 작업을 수행하는 응용 프로그램입니다. 코드가 메시지 처리기 내부에서 실행되는 동안 응용 프로그램이 다른 메시지 (스레드는 한 번에 하나씩 만 처리 할 수 ​​있음)를 처리 할 수 ​​없으며 UI가 응답하지 않기 때문에 제대로 작동하지 않습니다.

해결책은 다른 스레드 (또는 둘 이상이 필요함)를 스핀 오프하여 장기 실행, 계산 집약적 인 작업을 해당 스레드에 위임하는 것입니다. 단일 UI 스레드에서 여전히 메시지를 처리하지만 메시지 핸들러 내부에서는 도우미 스레드로 작업을 전달합니다. "작업자 스레드"또는 "배경 스레드"패턴이라고하는 것을 자주 듣게됩니다.

CreateThread function을 사용하여 추가 스레드를 만들 수 있습니다. 샘플 here을 찾을 수 있습니다.

이 경우 QueueUserWorkItem function이 더 간단한 옵션 일 수 있습니다. 예제 코드 :

DWORD CALLBACK ThreadProc(LPVOID p) 
{ 
    HWND hWnd = reinterpret_cast<HWND>(p); 

    for (int i = 0; i < 100000; ++i) 
    { 
     // do whatever 
    } 

    return 0; 
} 

LRESULT CALLBACK WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 
{ 
    switch (uMsg) 
    { 
     case WM_KEYDOWN: // or whatever message you want to respond to 
     { 
      QueueUserWorkItem(ThreadProc, hWnd, WT_EXECUTELONGFUNCTION); 
      return 0; 
     } 
     // process other messages... 
    } 
    return DefWindowProc(hWnd, uMsg, wParam, lParam); 
} 

Win32 스레드 풀에서 읽기는 here입니다.

+1

두 개 이상의 UI 스레드를 가질 수 있지만 각 창은 메시지가 전달 될 단 하나의 스레드와 연결됩니다. –

관련 문제