2011-12-26 2 views
3

"스레드 입력 큐"란 무엇입니까? MSDN에서 몇 번 언급 한 것을 보았습니다. 단순히 메시지 대기열인지, 아니면 의미있는 스레드에 의해 생성되는지는 궁금하지 않습니다.스레드 입력 큐

예 :

WH_MOUSE_LL 후크 당신이 에 대해 마우스 입력 이벤트를 모니터링 할 수는 스레드의 입력 큐에 게시합니다.

+0

제 생각에 1990 년대에 배웠던 것은 DOS에서의 키보드 버퍼와 비슷합니다 - 사용자가 프로세스가 처리 할 수있는 것보다 빠르게 입력하면 OS는 입력 (마우스, 키보드)을 큐에 넣습니다. 그들은 길을 잃지 않는다. –

+0

@UweKeim, 그건 내가 대략적으로 말했을 때. 마우스를 왼쪽으로 클릭하면 이벤트가 스레드 입력 대기열에 먼저 추가됩니다. 일단 대기열에서 빠져 나오고,해야 할 일을 마치면,'WM_LBUTTONDBLCLK' 메시지를 생성하고, 그것을 특정 윈도우의 메시지 대기열에 넣습니다. - 결국, 마우스 이벤트를 큐에 넣기 위해서는 스레드 입력 대기열을 먼저 통과해야하며 논리가 필요합니다 - 아니면 완전히 잘못 됐습니까? – ebb

+0

네, 그게 내 마음 속에서 묘사하는 방법입니다. "thread"와 "window"가 어떻게 다른지 명확하게 밝히지는 못했지만, 누군가가 훨씬 더 상세한 답변을 게시 할 것이라고 확신합니다 :-) –

답변

2

첫째, 창에는 개별 메시지 대기열이 없습니다. 윈도우에 대한 메시지는 관련된 스레드의 메시지 대기열에 보관됩니다.

According to MSDN 키보드 및 마우스 입력 메시지는 관련 창과 관련된 스레드의 메시지 큐로 보내집니다. 그래서 "스레드 입력 대기열"은 단순히 "스레드 메시지 대기열"을 말하는 또 다른 방법이라고 생각합니다.

편집 : Raymond는 AttachThreadInput 함수를 사용하여 입력을 다른 스레드의 메시지 대기열로 리디렉션 할 수 있다고 지적했습니다. 따라서 "스레드 입력 대기열"은 주어진 스레드에 대한 입력을받는 메시지 대기열을 의미합니다. 기본적으로 이것은 동일한 스레드의 메시지 대기열이지만 다른 스레드의 메시지 대기열이 될 수 있습니다.

+2

각 스레드에는 메시지 큐가 있습니다. 각 스레드 * 그룹 *에는 입력 대기열이 있습니다. –

+0

@ RaymondChen, 설명하는 어딘가의 문서? – ebb

+1

16 비트보기의 경우 Bob Gunderson의 "GetMessage 및 PeekMessage 내부"를 참조하십시오. Win16에는 시스템 전체에 걸친 단일 입력 대기열이 있지만 Win32에서는 각 스레드 그룹에 자체 입력 대기열이 있습니다. (쓰레드 그룹은 AttachThreadInput 함수에 의해 만들어졌으며, 그 함수가 무엇인지 궁금해하셨습니까?) 또한 "Win32 프로그래머가 알아야 할 다섯 가지"를 참조하십시오. –

0

실제 답변은 논리적 추상화 offered by the MSDN보다 약간 더 복잡합니다. 나는 받아 들인 대답의 코멘트에서 확인 된 것보다 더 자세히 대답 할 수있다.

예, 두 가지 메시지가 있습니다. "게시 메시지 대기열"과 "입력 메시지 대기열"이 있습니다. 후자에는 생 마우스 및 키보드 메시지 이벤트 목록이 포함되어 있습니다. 전자는 게시되고 합성 된 메시지를 포함합니다.

내부적으로 둘 다 그냥 목록이지만 입력 메시지 목록은 내부적으로 "입력 대기열"로 참조되는 더 큰 구조 내에 포함되어 있습니다. 구조에는 논리 큐에 대한 데이터와 원시 입력 메시지 목록에 대한 포인터가 포함됩니다.

이들은 또한 "응용 프로그램 대기열"및 "시스템 대기열"이라고 서로 바꿔서 사용할 수 있습니다.

GetMessage()은 별도로 처리합니다.

THREADINFO에는 게시 메시지 목록/대기열에 대한 포인터가 있습니다. QS_POSTMESSAGE이 설정된 경우 스캔됩니다. 어느 QS_INPUT 또는 QS_EVENT 큐 동상이 설정된 경우

가 입력리스트/큐 THREADINFO에서 초기 큐 구조 포인터 및 그 큐 구조로부터 입력리스트 포인터를 얻는 스캔된다. 이상한, 알아.

QS_TIMER 큐 상태 플래그가 설정되어있는 경우, GetMessage() (또는 PeekMessage()가) 실제로라는 누구든지에 "속"한다는 경고 상태로 최초의 타이머를 찾기 위해 전체 비 커널 타이머 목록의 스캔의 시작해야합니다 GetMessage(). 대기열에는 실제로 타이머가 실행 된 시간에 대한 정보가 저장되지 않습니다. 그들이 저장하는 관련 정보 만이 QS_TIMER 플래그와 트리거 된 타이머 수입니다 (GetMessage()은 사용 가능한 마지막으로 트리거 된 타이머에 대한 메시지를 합성 한 후에 QS_TIMER 대기열 상태를 지울시기를 알고 있습니다).)

다른 합성 메시지는 대기열 메시지의 실제 목록 외부에 저장된 데이터를 기반으로하지만 대기열 구조 자체의 다른 데이터는 여전히 "in"상태입니다.