Programing

메시지 펌프 란?

lottogame 2020. 8. 26. 08:22
반응형

메시지 펌프 란?


에서 이 스레드 (년 전에 게시) 비 대화식 세션에서 Word를 실행에 올 수있는 문제에 대한 논의가있다. 거기에 주어진 (아주 강한) 충고는 그렇게하지 말라는 것입니다. 한 게시물에서 "Office API는 모두 데스크톱에서 모니터, 키보드 및 마우스, 그리고 가장 중요한 메시지 펌프가있는 대화 형 세션에서 Office를 실행한다고 가정합니다." 그게 뭔지 모르겠어요. (저는 약 1 년 동안 C #으로 프로그래밍 해 왔으며 다른 프로그래밍 경험은 주로 ColdFusion에서 경험했습니다.)

최신 정보:

내 프로그램은 많은 수의 RTF 파일을 통해 의료 보고서 번호를 구성하는 데 사용되는 두 가지 정보를 추출합니다. RTF의 형식 지정 지침이 어떻게 작동하는지 알아 내기보다는 Word에서 열어 텍스트를 꺼내기로 결정했습니다 (실제로 GUI를 시작하지 않음). 때때로 프로그램은 하나의 파일을 처리하는 도중에 문제가 발생하여 해당 문서에 첨부 된 Word 스레드를 열어 두었습니다 (아직도 파일을 종료하는 방법을 알아 내야합니다). 프로그램을 다시 실행하면 당연히 해당 파일을 사용하는 스레드가 있다는 알림을 받았으며 읽기 전용 복사본을 열고 싶었습니까? 예라고 말했을 때 갑자기 Word GUI가 갑자기 나타나서 파일 처리를 시작했습니다. 왜 그런 일이 일어 났는지 궁금합니다.


메시지 루프는 모든 기본 Windows 프로그램에 존재하는 작은 코드 조각입니다. 대략 다음과 같습니다.

MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{ 
   TranslateMessage(&msg); 
   DispatchMessage(&msg); 
} 

GetMessage () Win32 API는 Windows에서 메시지를 검색합니다. 프로그램은 일반적으로 Windows에서 흥미로운 일이 발생했음을 알리는 데 99.9 %의 시간을 보냅니다. TranslateMessage ()는 키보드 메시지를 번역하는 도우미 함수입니다. DispatchMessage ()는 창 프로 시저가 메시지와 함께 호출되도록합니다.

모든 GUI 사용 .NET 프로그램에는 메시지 루프가 있으며 Application.Run ()에 의해 시작됩니다.

Office에 대한 메시지 루프의 관련성은 COM과 관련이 있습니다. Office 프로그램은 COM 사용 가능 프로그램이므로 Microsoft.Office.Interop 클래스가 작동합니다. COM은 COM coclass를 대신하여 스레딩을 처리하며 COM 인터페이스에 대한 호출이 항상 올바른 스레드에서 이루어 지도록합니다. 대부분의 COM 클래스에는 ThreadingModel을 선언하는 레지스트리 키가 레지스트리에 있으며, 가장 일반적인 클래스 (Office 포함)는 "Apartment"를 사용합니다. 즉, 인터페이스 메서드를 호출하는 유일한 안전한 방법은 클래스 개체를 만든 동일한 스레드에서 호출하는 것입니다. 또는 다른 말로하면 대부분의 COM 클래스는 스레드로부터 안전하지 않습니다.

모든 COM 사용 스레드는 COM 아파트에 속합니다. STA (Single Threaded Apartments)와 MTA (Multi Thread Apartment)의 두 가지 종류가 있습니다. 아파트 스레드 COM 클래스는 STA 스레드에서 만들어야합니다. .NET 프로그램에서 다시 볼 수 있습니다. Windows Forms 또는 WPF 프로그램의 UI 스레드 진입 점에는 [STAThread] 특성이 있습니다. 다른 스레드에 대한 아파트 모델은 Thread.SetApartmentState () 메서드에 의해 설정됩니다.

UI 스레드가 STA가 아닌 경우 Windows 배관의 많은 부분이 제대로 작동하지 않습니다. 특히 Drag + Drop, 클립 보드, OpenFileDialog와 같은 Windows 대화 상자, WebBrowser와 같은 컨트롤, 화면 판독기와 같은 UI 자동화 앱이 있습니다. 그리고 Office와 같은 많은 COM 서버.

STA 스레드에 대한 엄격한 요구 사항은 차단하지 않아야하고 메시지 루프를 펌핑해야한다는 것입니다. 메시지 루프는 COM이 한 스레드에서 다른 스레드로 인터페이스 메서드 호출을 마샬링하는 데 사용하기 때문에 중요합니다. .NET을 사용하면 마샬링 호출이 쉬워 지지만 (예 : Control.BeginInvoke 또는 Dispatcher.BeginInvoke) 실제로 수행하기 매우 까다로운 작업입니다. 호출을 실행하는 스레드는 잘 알려진 상태 여야합니다. 스레드를 임의로 인터럽트하고 메서드 호출을 강제 할 수는 없습니다. 이는 끔찍한 재진입 문제를 유발할 수 있습니다. 스레드는 프로그램 상태를 변경하는 코드를 실행 하느라 바쁘지 않고 "유휴"상태 여야합니다.

아마도 그것이 어디로 이끄는지를 볼 수있을 것입니다. 예, 프로그램이 메시지 루프를 실행할 때 그것은 유휴 상태입니다. 실제 마샬링은 COM이 만든 숨겨진 창을 통해 발생하며 PostMessage를 사용하여 해당 창의 창 프로 시저가 코드를 실행하도록합니다. STA 스레드에서. 메시지 루프는이 코드가 실행되도록합니다.


"메시지 펌프"는 응용 프로그램의 다양한 부분에 윈도우 메시지를 발송하는 역할을하는 모든 Windows 프로그램의 핵심 부분입니다. 이것이 Win32 UI 프로그래밍의 핵심입니다. 편재성 때문에 많은 응용 프로그램이 메시지 펌프를 사용하여 서로 다른 모듈간에 메시지를 전달하기 때문에 UI없이 실행하면 Office 응용 프로그램이 중단됩니다.

Wikipedia에는 기본적인 설명이 있습니다.


John은 Windows 시스템 (및 기타 창 기반 시스템 -X Window , 원래 Mac OS ....)이 메시지 시스템을 통해 이벤트를 사용하여 비동기 사용자 인터페이스를 구현 하는 방법에 대해 이야기하고 있습니다.

각 애플리케이션의이면에는 각 창이 다른 창이나 이벤트 리스너에 이벤트를 보낼 수있는 메시징 시스템이 있습니다. 이는 메시지 대기열에 메시지를 추가하여 구현됩니다. 항상이 메시지 큐를보고 리스너에게 메시지 (또는 이벤트)를 전달하는 메인 루프가 있습니다.

Wikipedia 기사 Microsoft Windows의 메시지 루프 는 기본 Windows 프로그램의 예제 코드를 보여줍니다. 가장 기본적인 수준에서 볼 수 있듯이 Windows 프로그램은 "메시지 펌프"일뿐입니다.

그래서 그것을 모두 모으십시오. UI를 지원하도록 설계된 Windows 프로그램이 서비스 역할을 할 수없는 이유는 UI 지원을 활성화하기 위해 항상 실행되는 메시지 루프가 필요하기 때문입니다. 설명 된대로 서비스로 구현하면 내부 비동기 이벤트 처리를 처리 할 수 ​​없습니다.


에서 COM 메시지 펌프 serialises와 드 serialises 메시지는 아파트 사이에 전송. 아파트는 COM 구성 요소를 실행할 수있는 미니 프로세스입니다. 아파트는 단일 스레드 및 자유 스레드 모드로 제공됩니다. 단일 스레드 아파트는 주로 다중 스레드를 지원하지 않는 COM 구성 요소의 응용 프로그램을위한 레거시 시스템입니다. 일반적으로 Visual BASIC (멀티 스레드 코드를 지원하지 않았기 때문에) 및 레거시 애플리케이션과 함께 사용되었습니다.

I guess that the message pump requirement for Word stems from either the COM API or parts of the application not being thread safe. Bear in mind that the .NET threading and garbage collection models don't play nicely with COM out of the box. COM has a very simplistic garbage collection mechanism and threading model that requires you to do things the COM way. Using the standard Office PIAs still requires you to explicitly shut down COM object references, so you need to keep track of every COM handle created. The PIAs will also create stuff behind the scenes if you're not careful.

.NET-COM integration is a whole topic all by itself, and there are even books written on the subject. Even using COM APIs for Office from an interactive desktop application requires you to jump through hoops and make sure that references are explicitly released.

Office can be assumed to be thread-unsafe, so you will need a separate instance of Word, Excel or other Office applications for each thread. You would have to incur the starting overhead or maintain a thread pool. A thread pool would have to be meticulously tested to make sure all COM references were correctly released. Even starting and shutting down instances requires you to make sure all references are released correctly. Failure to dot your i's and cross your t's here will result in large numbers of dead COM objects and even whole running instances of Word being leaked.


Wikipedia suggests it means the program's main Event Loop.


I think that this Channel 9 discussion has a nice succinct explanation:

This process of window communication is made possible by the so-called Windows Message Pump. Think of the Message Pump as an entity that enables cooperation between application windows and the desktop.

참고URL : https://stackoverflow.com/questions/2222365/what-is-a-message-pump

반응형