Single-Threaded 아파트

단일 스레드 아파트 (아파트 모델 프로세스)를 사용 하면 동시에 실행 되는 여러 개체를 처리 하기 위한 메시지 기반 패러다임을 제공 합니다. 이를 통해 스레드를 허용 하는 동시에 시간이 많이 걸리는 작업이 완료 될 때까지 대기 하는 동안 다른 스레드를 실행할 수 있도록 하 여 보다 효율적인 코드를 작성할 수 있습니다.

아파트 모델 프로세스로 초기화 되 고 창 메시지를 검색 하 고 디스패치할 프로세스의 각 스레드는 단일 스레드 아파트 스레드입니다. 각 스레드는 자체 아파트 내에 있습니다. 아파트 내에서는 마샬링을 사용 하지 않고 인터페이스 포인터를 전달할 수 있으므로 하나의 단일 스레드 아파트 스레드의 모든 개체가 직접 통신 합니다.

모두 동일한 스레드에서 실행 되는 관련 개체의 논리적 그룹화 이며 동기 실행이 있어야 합니다. 동일한 단일 스레드 아파트 스레드에 존재할 수 있습니다. 그러나 아파트 모델 개체는 둘 이상의 스레드에 상주할 수 없습니다. 다른 스레드의 개체에 대 한 호출은 소유 스레드의 컨텍스트 내에서 이루어져야 하므로, 프록시에서를 호출 하면 분산 COM에서 자동으로 스레드를 전환 합니다.

프로세스간 및 상호 스레드 모델은 비슷합니다. 동일한 프로세스 내에서 다른 아파트의 개체에 대 한 인터페이스 포인터를 전달 해야 하는 경우 다른 프로세스의 개체가 프로세스 경계를 넘어 포인터를 전달 하는 데 사용 하는 것과 동일한 마샬링 모델을 사용 합니다. 표준 마샬링 개체에 대 한 포인터를 가져오면 프로세스 사이에서 수행 하는 것과 동일한 방식으로 여러 스레드 경계 (아파트 간)에서 인터페이스 포인터를 마샬링할 수 있습니다. (인터페이스 포인터는 아파트 간에 전달 될 때 마샬링되어야 합니다.)

단일 스레드 아파트에 대 한 규칙은 간단 하지만 신중 하 게 따라야 합니다.

  • 모든 개체는 단일 스레드 아파트 내에서 하나의 스레드에서만 있어야 합니다.
  • 각 스레드에 대 한 COM 라이브러리를 초기화 합니다.
  • 아파트 간에 전달할 때 개체에 대 한 모든 포인터를 마샬링합니다.
  • 각 단일 스레드 아파트에는 동일한 프로세스 내에서 다른 프로세스와 아파트의 호출을 처리 하는 메시지 루프가 있어야 합니다. 개체가 없는 단일 스레드 아파트 (클라이언트 전용)에는 일부 응용 프로그램에서 사용 하는 브로드캐스트 메시지를 디스패치 하는 메시지 루프가 필요 합니다.
  • DLL 기반 또는 in-process 개체는 COM 초기화 함수를 호출 하지 않습니다. 대신 레지스트리의 InprocServer32 키 아래에 있는 ThreadingModel 명명 된 값을 사용 하 여 스레딩 모델을 등록 합니다. 또한 아파트 인식 개체는 DLL 진입점을 신중 하 게 작성 해야 합니다. 스레딩 in-process 서버에 적용 되는 특별 한 고려 사항이 있습니다. 자세한 내용은 In-process 서버 스레딩 문제를 참조 하세요.

여러 개체가 단일 스레드에 존재할 수 있지만 아파트 모델 개체는 둘 이상의 스레드에 존재할 수 없습니다.

클라이언트 프로세스의 각 스레드나 out-of-process 서버는 CoInitialize를 호출 하거나 CoInitializeEx 를 호출 하 고 _ dwcoinit 매개 변수에 coinit APARTMENTTHREADED를 지정 해야 합니다. 주 아파트는 CoInitializeEx 를 먼저 호출 하는 스레드입니다. In-process 서버에 대 한 자세한 내용은 In-process 서버 스레딩 문제를 참조 하세요.

개체에 대 한 모든 호출은 해당 스레드 (아파트 내)에서 수행 되어야 합니다. 다른 스레드에서 직접 개체를 호출할 수 없습니다. 이 자유 스레드된 방식으로 개체를 사용 하면 응용 프로그램에 문제가 발생할 수 있습니다. 이 규칙의 의미는 개체에 대 한 모든 포인터를 아파트 간에 전달 될 때 마샬링되어야 합니다. COM은 이러한 용도로 다음과 같은 두 가지 함수를 제공 합니다.

이러한 함수는 MSHCTX INPROC 플래그를 사용 해야 하는 ComarshalinterfaceCoUnmarshalInterface 함수에 대 한 호출을 래핑합니다 _ .

일반적으로 마샬링은 COM에서 자동으로 수행 됩니다. 예를 들어 프록시에 대 한 메서드 호출의 매개 변수로 다른 아파트의 개체에 대 한 인터페이스 포인터를 전달 하거나, CoCreateInstance를 호출 하는 경우 COM에서 마샬링을 자동으로 수행 합니다. 그러나 응용 프로그램 작성기에서 일반적인 COM 메커니즘을 사용 하지 않고 아파트 간에 인터페이스 포인터를 전달 하는 특별 한 경우에는 작성기에서 마샬링을 수동으로 처리 해야 합니다.

프로세스의 한 아파트 (아파트 1)에 인터페이스 포인터가 있고 다른 아파트 (아파트 2)가 사용 해야 하는 경우 아파트 1은 CoMarshalInterThreadInterfaceInStream 를 호출 하 여 인터페이스를 마샬링해야 합니다. 이 함수에서 만든 스트림은 스레드로부터 안전 하며, 아파트 2에서 액세스할 수 있는 변수에 저장 해야 합니다. 아파트 2는이 스트림을 Coget트랜잭션의 역마샬링 위해 Andreleasestream 에 전달 하 여 인터페이스를 하 고 인터페이스에 액세스할 수 있는 프록시에 대 한 포인터를 반환 해야 합니다. 주 아파트는 In-process 서버 스레딩 문제에 설명 된 대로 일부 in-process 개체가 주 아파트에 로드 되기 때문에 클라이언트가 모든 COM 작업을 완료할 때까지 활성 상태를 유지 해야 합니다. 이러한 방식으로 스레드 간에 하나의 개체가 전달 된 후에는 인터페이스 포인터를 매개 변수로 전달 하기가 매우 쉽습니다. 이렇게 하면 분산 COM이 응용 프로그램에 대 한 마샬링 및 스레드 전환을 수행 합니다.

동일한 프로세스 내에서 다른 프로세스와 아파트의 호출을 처리 하려면 각 단일 스레드 아파트에 메시지 루프가 있어야 합니다. 이는 스레드의 작업 함수에 GetMessage/DispatchMessage 루프가 있어야 함을 의미 합니다. 다른 동기화 기본 형식을 사용 하 여 스레드 간에 통신 하는 경우 MsgWaitForMultipleObjects 함수를 사용 하 여 메시지와 스레드 동기화 이벤트를 모두 대기할 수 있습니다. 이 함수에 대 한 설명서에는 이러한 종류의 조합 루프의 예가 포함 되어 있습니다.

COM은 각 단일 스레드 아파트에서 Windows 클래스 "OleMainThreadWndClass"를 사용 하 여 숨겨진 창을 만듭니다. 개체에 대 한 호출은이 숨겨진 창에 창 메시지로 수신 됩니다. 개체의 아파트에서 메시지를 검색 하 고 디스패치할 때 숨겨진 창에서 메시지를 받습니다. 그러면 창 프로시저는 개체의 해당 인터페이스 메서드를 호출 합니다.

여러 클라이언트에서 개체를 호출 하면 메시지가 메시지 큐에서 큐에 대기 되 고 개체가 메시지를 검색 하 고 디스패치할 때마다 호출을 받게 됩니다. 호출은 COM에서 동기화 되 고, 개체의 아파트에 속하는 스레드에서 호출을 항상 전달 하므로 개체의 인터페이스 구현에서 동기화를 제공 하지 않아도 됩니다. 단일 스레드 아파트는 필요한 경우 호출을 취소 하거나 창 메시지를 수신할 수 있도록 imessagefilter.prefiltermessage 를 구현할 수 있습니다.

해당 인터페이스 메서드 구현 중 하나가 메시지를 검색 및 디스패치 하거나 다른 스레드에 대 한 ORPC 호출을 수행 하 여 동일한 아파트에서 다른 호출을 개체에 전달 하는 경우 개체를 다시 입력할 수 있습니다. OLE는 동일한 스레드에서 재진입을 방지 하지 않지만 스레드 안전을 제공 하는 데 도움이 됩니다. 이는 메시지를 처리 하는 동안 메시지를 검색 하 고 디스패치할 때 창 프로시저를 다시 입력할 수 있는 방식과 동일 합니다. 그러나 다른 단일 스레드 아파트 서버를 호출 하는 out-of-process 단일 스레드 아파트 서버를 호출 하면 첫 번째 서버를 다시 입력할 수 있습니다.

아파트에서 인터페이스 액세스

스레딩 모델 선택

다중 스레드 아파트

In-process 서버 스레딩 문제

프로세스, 스레드 및 아파트

단일 스레드 및 다중 스레드 통신