정보: 설명 및 ole 모델 스레딩 작업


요약


프로세스의 여러 스레드에서 COM 개체를 사용할 수 있습니다. "단일 스레드 아파트" 용어 (STA) "다중 스레드 아파트" (MTA) 개체 및 개체를 어떤 방법으로 수단 간의 동시성 관계 스레드 간의 관계를 설명 하기 위한 개념적 프레임 워크를 만드는 데 사용 되 고 호출 개체를 스레드 간에 인터페이스 포인터를 전달 하기 위한 규칙을 전달 합니다. 구성 요소와 클라이언트의 현재 COM에 의해 지원 다음 두 가지 아파트 모델 간의 선택:

  1. 단일 스레드 아파트 모델 (STA): 프로세스에서 여러 스레드를 사용 하 여 COM 및 COM 개체를 호출 하 여 동기화 스레드 간에 인터페이스 COM. 마샬링됩니다. 지정된 된 프로세스의 스레드가 하나만 COM을 사용 하는 단일 스레드 아파트 모델의 디 제너 레이트 경우 단일 스레드 모델을 이라고 합니다. 이전 Microsoft 정보 및 설명서가 라고도 STA 모델에서는 단순히 "아파트 모델."
  2. 다중 스레드 아파트 (MTA) 모델: 하나 이상의 스레드에서 COM을 사용 하 고 MTA와 연결 된 COM 개체에는 호출 개체와 호출자 사이 시스템 코드의 모든 interposition 없이 MTA와 관련 된 모든 스레드를 직접. 호출 하기 때문에 여러 동시 클라이언트 수 수 개체 적게 동시에 (동시에 다중 프로세서 시스템의 경우), 개체 자체의 내부 상태를 동기화 해야 합니다. 인터페이스는 스레드 간에 마샬링되지 않습니다. 이전 Microsoft 정보 및 설명서에이 라고도이 모델은 "자유 스레드 모델."
  3. STA 모델 및 MTA 모델이 모두 동일한 프로세스에서 사용할 수 있습니다. 이를 "혼합 모델" 프로세스라고도 합니다.
MTA NT 4.0에 도입 된 및 DCOM95와 Windows 95에서 사용할 수 있습니다. STA 모델에서는 Windows NT 3.51 및 Windows 95 및 NT 4.0 DCOM95와 Windows 95에서 존재합니다.

자세한 내용


개요

다른 스레딩 아키텍처를 사용 하 여 함께 작동 하도록 하는 구성 요소에 대 한 메커니즘을 제공 하는 com에서 스레딩 모델입니다. 수행 하는 구성 요소를 동기화 서비스 제공. 예를 들어, 특정 개체 스레드 하나 에서만 호출 되도록 디자인 됩니다 및 클라이언트의 동시 호출이 동기화 할 수 없습니다. 이러한 개체를 여러 스레드에서 동시에 호출 하면 충돌 또는 오류가 발생 합니다. COM은 아키텍처 스레딩의이 상호 운용성을 처리 하기 위한 메커니즘을 제공 합니다.

심지어 스레드 인식 구성 요소 동기화 서비스가 필요한 경우가 많습니다. 예를 들어, OLE/ActiveX 컨트롤과 내부 현재 포함을 ActiveX 문서 같은 그래픽 사용자 인터페이스 (GUI)를 가진 구성 요소 동기화 및 COM 호출 및 창 메시지를 직렬화 해야 합니다. COM 복잡 한 동기화 코드 없이 이러한 구성 요소를 작성할 수 있도록 이러한 동기화 서비스를 제공 합니다.

"아파트" 상호 관련된 몇 가지 측면에 있습니다. 첫째, 논리 구문을 스레드 COM 개체 집합을 관계와 같이 동시성에 대 한 생각에는. 둘째, 일련의 규칙 프로그래머는 COM 환경에서 기대 하는 동시성 동작을 받으려는 준수 해야 됩니다. 마지막으로, 프로그래머가 COM 개체에 대 한 스레드 동시성을 관리할 수 있는 시스템 제공 하는 코드는.

개의 집합으로 관련 되지만 다른 "로캘" 이라는 "아파트."가을 "구축" 하는 등 완전히 분리 된 개체로 완전히 프로세스를 하는 메타포에서 "아파트" 라는 용어는 아파트는 개체 사이의 및, 경우에 따라서는 스레드 연결 "논리 컨테이너"입니다. 스레드가 단일 스레드 아파트 STA 모델에서을 사용 하 여 논리적으로 관련 된 있을 수 있지만, 아파트 않습니다. 개체는 모든 개체는 하나만 아파트와 관련 되지만 아파트를 없습니다. 하지만 아파트는 단순한 논리 구조. COM 시스템의 동작을 설명 하는 규칙입니다. 아파트 모델의 규칙을 따르지 않으면 COM 개체가 제대로 작동 하지 않습니다.

자세한 내용을 보려면

단일 스레드 아파트 (STA) 특정 스레드와 관련 된 COM 개체 집합입니다. 하 여 스레드에 의해 생성 되 고 이러한 개체는 연결 된 아파트 또는 더 정확 하 게 먼저 노출 되지 COM 시스템 (일반적으로 마샬링)에서 스레드. STA 개체를 장소를 간주 됩니다 또는 프록시 "거주 하 고 있습니다." 개체 또는 프록시 다른 아파트 (같은 또는 다른 프로세스)에 액세스할 수 있어야, 인터페이스 포인터는 새 프록시가 만들어질 위치 해당 아파트 마샬링되어야 합니다. 아파트 모델의 규칙을 따르는 동일한 프로세스의 다른 스레드에서 직접 호출 하지 않고는 해당 개체에 사용할 수 단일 스레드에서 실행 되는 특정된 아파트 내의 모든 개체 규칙을 위반 하는. STA에서 실행 되는 대부분 코드가 추가 스레드를 실행 하는 경우 제대로 작동 되지 것입니다 규칙이 존재 합니다.

관련 된 STA 스레드 CoInitializeEx (NULL, COINIT_APARTMENTTHREADED) 또는 CoInitialize를 호출 해야 하 고 검색 고 연결 된 개체 들어오는 호출 받기 위해 창 메시지를 발송 해야 합니다. COM 디스패치합니다 및이 문서의 뒷부분에 설명 된 것 처럼 창 메시지를 사용 하 여 sta에서 개체에 대 한 호출을 동기화 합니다.

"주 STA"는 지정된 된 프로세스 내에서 CoInitialize 또는 CoInitializeEx(NULL,COINIT_APARTMENTTHREADED)를 먼저 호출 하는 스레드입니다. 모든 COM 작업을 완료할 때까지 일부 프로시저에 개체가 항상 주 STA에 로드 됩니다 때문에이 문서의 뒷부분에 설명 된 대로 프로세스의 주 STA 살아 있어야 합니다.

Windows NT 4.0과 DCOM95 아파트 다중 스레드 아파트 (MTA) 라는 새로운 유형의 소개 합니다. MTA는 스레드가 직접 interposition 시스템 코드 없이 모든 개체 구현을 호출할 수 있는 프로세스의 스레드 집합이 관련 된 COM 개체 집합입니다. MTA에서 모든 개체에 대 한 인터페이스 포인터는 마샬링할 수 않고도 MTA와 관련 된 스레드 간에 전달할 수 있습니다. CoInitializeEx (NULL, COINIT_MULTITHREADED)를 호출 하는 프로세스의 모든 스레드가 MTA와 연결 됩니다. 위에서 설명한 STA를 달리는 MTA 스레드를 검색 하 여 연결 된 개체 들어오는 호출 받기 위해 창 메시지를 디스패치하기 않아도 됩니다. COM에서 호출은 MTA의 개체를 동기화 하지 않습니다. MTA 개체의 다중 동시 스레드 상호 작용에 의해 손상에서 내부 상태를 보호 해야 하 고 다른 메서드 호출 사이의 스레드 로컬 저장소 나머지 상수의 내용에 대 한 모든 가정을 만들 수 없습니다.

프로세스는 Sta 개수에 제한 없이 가질 수 있지만 기껏해야 한 MTA 가질 수 있습니다. 하나 이상의 스레드가 MTA 구성 됩니다. Sta 스레드를 하나씩가지고. 스레드 한 아파트에 기껏해야 속해 있습니다. 개체는 하나만 아파트 속합니다. (마샬링 한 결과를 프록시 대신에 대 한 직접적인 포인터를 수 있습니다) 하지만 아파트 간에 인터페이스 포인터는 마샬링할 수 항상. CoCreateFreeThreadedMarshaler에 아래 정보를 참조 하십시오.

프로세스를 com에서 제공 된 스레딩 모델 중 하나를 선택 합니다. 한 STA 모델의 프로세스 하나 이상의 Sta 있으며 MTA는 없습니다. 한 MTA 모델 프로세스 하나 이상의 스레드를 사용 하 여 한 MTA가 있고 모든 Sta 없습니다. 혼합 모델 프로세스에 한 MTA 및 Sta 수에.

단일 스레드 아파트 모델

STA 스레드가 CoInitialize 또는 CoInitializeEx (NULL, COINIT_APARTMENTTHREADED)를 호출 해야 하 고 검색 고 COM 창 메시지를 사용 하 여 동기화 하는이 모델에 있는 개체에 대 한 호출을 발송 하기 때문에 창 메시지를 발송 해야 합니다. 자세한 내용은 ' 참조 ' 절을 참조 하십시오.

STA 모델을 지 원하는 서버:

STA 모델의 개체에 대 한 호출 창에 게시 한 창 메시지를 동기화가 동일한 방식으로 COM에서 동기화 됩니다. 호출 개체를 만든 스레드와 창 메시지를 사용 하 여 전달 해야 합니다. 따라서 현재 스레드는 Get/PeekMessage와 DispatchMessage 호출을 받을 수를 호출 해야 합니다. COM 만듭니다 각 STA.와 관련 된 숨겨진된 창 해당 STA 외부에서 개체에 대 한 호출 COM 런타임에서 개체의 스레드가이 숨겨진된 창에 게시 한 창 메시지를 사용 하 여 전송 됩니다. 연결 된 개체의 STA 스레드를 검색 메시지 디스패치 숨겨진된 창 또한 COM에 의해 구현에 대 한 창 프로시저가를 받습니다. 창 프로시저는 COM 런타임에서 "후크" COM 런타임은 COM 소유한 스레드에서 호출 하면 STA 스레드 양쪽에 때문에 STA 함께 연결 하는 데 사용 됩니다. (이제 해당 STA 스레드에서 실행) COM 런타임을 "작동 중" COM 제공한 스텁 통해 개체의 해당 인터페이스 메서드로 호출 합니다. 메서드 호출에서 반환 하는 실행 경로 취소 "를" 호출; 스텁 및 다음 COM 채널을 통해 원래 호출자로 반환 되는 창 메시지를 통해 COM 런타임 스레드에로 다시 제어를 전달 하는 COM 런타임 호출이 반환 됩니다.

STA 개체를 호출 하는 여러 클라이언트 호출 하 여 자동으로 대기 중인 메시지 큐에 전송 제어 메커니즘을 사용 하는 STA.에 의해 개체의 STA 검색 하 고 메시지를 디스패치합니다 때마다 호출을 받습니다. 이런 방식으로 호출 하 여 COM에서 동기화 및 연결 된 개체의 STA 단일 스레드에서 호출이 항상 배달 하기 때문에 개체의 인터페이스 구현을 동기화 제공할 필요는 없습니다.

참고: 인터페이스 메서드를 구현할 때 검색 하 고 호출 하 여 동일한 STA. 개체에 전달 되어 메서드 호출을 처리 하는 동안 메시지를 디스패치합니다 경우 개체가 다시 입력 될 수 있습니다 이 발생 하는 일반적인 방법은 경우 STA 개체는 COM.를 사용 하는 나가는 (아파트/간-프로세스 간) 호출 됩니다. 창 프로시저를 사용할 수 있는 다시 입력을 검색 하 고 메시지를 처리 하는 동안 메시지를 디스패치합니다 방식으로 하는 것과 같습니다. COM 때도 동일한 스레드에서 회신 입구 없지만 동시 실행 하지 않습니다. 또한 COM 관련 재진입 관리할 수 있는 수단을 제공 합니다. 자세한 내용은 ' 참조 ' 절을 참조 하십시오. 개체가 없는 경우 회신-메서드 구현을 해당 아파트를 호출 하거나 그렇지 않으면 검색 및 금지 메시지를 발송 하는 경우 입력

STA 모델에서의 책임 클라이언트:

프로세스 또는 스레드에 STA 모델을 사용 하 여 실행 하는 클라이언트 코드의 CoMarshalInterThreadInterfaceInStream 및 CoGetInterfaceAndReleaseStream를 사용 하 여 아파트 간에 개체 인터페이스 마샬링해야 합니다. 예를 들어, 클라이언트에서 아파트 1에 대 한 인터페이스 포인터 아파트 2에 그를 사용 해야 하는 경우 아파트 1 CoMarshalInterThreadInterfaceInStream를 사용 하 여 인터페이스를 마샬링해야 합니다. 이 함수에 의해 반환 되는 stream 개체는 스레드로부터 안전 하 고 아파트 2 인터페이스 포인터를 직접 메모리 변수에 액세스할 수 저장 합니다. 아파트 2 내부 개체의 인터페이스를 역마샬링 프록시 개체가 액세스할 수 있는 포인터를 다시 가져오는 데 CoGetInterfaceAndReleaseStream 하이 스트림 인터페이스를 통과 해야 합니다.

일부 프로세서에서 개체는 주 아파트에 로드 되기 때문에 클라이언트 COM 작업을 모두 완료할 때까지 해당된 프로세스의 주 아파트 살아 있어야 합니다. (자세한 정보는 아래에서 설명).

다중 스레드 아파트 모델

MTA 생성 되거나 (NULL, COINIT_MULTITHREADED) CoInitializeEx를 호출 하는 프로세스의 모든 스레드를 노출 하는 개체의 컬렉션입니다.

참고: com 현재 구현을 사용에 MTA의 일부가 될 COM 명시적으로 초기화 되지 않습니다. COM을 초기화 하지 않는 스레드는 프로세스에서 하나 이상의 다른 스레드가 호출 후에 이전에 CoInitializeEx (NULL, COINIT_MULTITHREADED) COM을 사용 하 여 시작 하는 경우에 일부 MTA입니다. (COM 초기화 MTA 스레드가 클라이언트 명시적으로 초기화 하는 경우, 예를 들어 관련 된 STA 스레드 호출 CoGetClassObject/CoCreateInstance [Ex]에 표시 된 CLSID는 수도 "ThreadingModel 있음 =" 및 COM 암시적으로 만들어집니다 MTA 클래스 개체를 로드 합니다.) 스레딩 모델 상호 운용성 아래에 정보를 참조 하십시오.

그러나 특정 상황에서 액세스 위반과 같은 문제가 발생할 수 있는 구성입니다. 따라서 각 스레드에서 COM 작업을 수행 하는 CoInitializeEx를 호출 하 여 COM을 초기화 하 고 COM 작업 완료 시 CoUninitialize를 호출 다음 것이 좋습니다. "불필요 하 게" MTA 초기화 하는 비용이 최소화 됩니다.

MTA 스레드 검색 하 고 COM 사용 하지 않는 창 메시지가 모델에서 개체에 대 한 호출을 제공 하기 때문에 메시지를 발송할 필요가 없습니다.

MTA 모델을 지 원하는 서버:

MTA 모델 개체에 대 한 호출에 COM. 여러 클라이언트에서 동시에 지 원하는이 모델을 다른 스레드와 개체에서 제공 하는 동기화를 사용 하 여 해당 인터페이스/메서드 구현을 개체를 호출할 수 동기화 되지 않습니다. 이벤트, 뮤텍스, 세마포 등 같은 동기화 개체입니다. MTA 개체는 개체의 프로세스에 속하는 COM에서 만든 스레드 풀을 통해 여러 작업 중이 아닌 클라이언트에서 동시 호출을 받을 수 있습니다. MTA 개체 MTA와 연결 된 다중 스레드 프로세스에서 여러 클라이언트에서 동시 호출을 받을 수 있습니다.

MTA 모델에서의 책임 클라이언트:

프로세스 또는 MTA 모델을 사용 하는 스레드를 실행 하는 클라이언트 코드가 개체 자체와 다른 MTA 스레드 간에 인터페이스 포인터를 마샬링할 필요가 없습니다. 대신, 한 MTA 스레드가 다른 MTA 스레드가 직접 메모리 포인터로 얻은 인터페이스 포인터를 사용할 수 있습니다. 클라이언트 스레드는 작업 중이 아닌 개체에 대 한 호출을 하면 해당 호출이 완료 될 때까지 일시 중단 합니다. 지속적인 아웃 호출 MTA와 연결 된 모든 응용 프로그램에서 만든 스레드 차단 된 동안 MTA와 연결 된 개체에 호출이 도착할 수 있습니다. 이 경우 고 일반적으로 들어오는 호출 스레드에서 COM 런타임에서 제공 배달 됩니다. 메시지 필터 (IMessageFilter) MTA 모델에 사용 하기 위해 사용할 수 있습니다.

혼합 스레딩 모델

혼합 스레딩 모델을 지 원하는 프로세스를 한 MTA 사용할 및 하나 이상의 Sta. 인터페이스 포인터를 모든 아파트 간 마샬링되어야 있지만 내에서 MTA 마샬링 없이 사용할 수 있습니다. Sta에서 개체에 대 한 호출 MTA의 개체에 대 한 호출 되지 않는 반면 단 하나의 스레드에서 실행 되도록 COM에서 동기화 됩니다. 그러나 MTA에서 STA 호출 일반적으로 시스템에서 제공 하는 코드를 통해가 서 개체에 배달 전에 MTA 스레드는 STA 스레드에서 전환 합니다.

참고: 직접 포인터를 사용할 수 있는,의 경우에 대 한 내용은 아래의 해당 API에 대 한 설명 및 CoCreateFreeThreadedMarshaler() SDK 설명서를 참조 하 고 STA 스레드 개체를 직접 호출할 수 어떻게 먼저 MTA와 관련 된, 여러 아파트에서.

스레딩 모델 선택

STA 모델, MTA 모델 또는 혼합 스레딩 모델을 사용 하 여 두 조합을 지원 하기 위해 구성 요소를 선택할 수 있습니다. 예를 들어, 광범위 한 I/O를 수행 하는 개체 인터페이스 호출 하는 동안 I/O 대기 시간을 허용 함으로써 클라이언트에 최대 응답을 제공 하기 위해 MTA 지원 하도록 선택할 수 있습니다. 또한 GUI 작업을 사용 하 여 들어오는 COM 호출을 동기화 하려면 STA 지원 하도록 거의 항상 사용자와 상호 작용 하는 개체를 선택 합니다. STA 모델의 지 원하는 COM 동기화를 제공 하므로 쉽습니다. 개체가 동기화를 구현 해야 하지만 클라이언트에 대 한 응답이 전체 인터페이스 호출 com 제공 보다는 작은 코드 섹션에 대 한 동기화 사용 되기 때문에 더 나은 더 어렵습니다 MTA 모델을 지원 합니다.

STA 모델 에서도 Microsoft 트랜잭션 서버 (MTS, 이전 코드명된 "Viper")를 사용 하 고 MTS 환경 내에서 실행 하려는 DLL 기반 개체 따라서 STA 모델을 사용 해야 합니다. MTA 모델에 대해 구현 된 개체 정상적으로 MTS 환경에서 제대로 작동 합니다. 그러나 실행 덜 효율적으로 불필요 한 스레드 동기화 기본 형식을 사용 하기 때문에.

In-proc 서버 지원-스레딩 모델을 표시

CoInitializeEx (NULL, COINIT_MULTITHREADED)를 호출 하거나 COM을 사용 하 여 초기화 하지 않고 스레드 MTA 모델을 사용 합니다. CoInitializeEx (NULL, COINIT_APARTMENTTHREADED) 또는 CoInitialize를 호출 하는 경우 스레드에서 STA 모델을 사용 합니다.

CoInitialize Api 패키지 된 개체와 클라이언트 코드 아파트 제어를 제공 합니다. Exe, COM 런타임 시작 코드가 원하는 방식으로 COM을 초기화할 수 있기 때문에.

그러나 프로세서 (DLL 기반) COM 서버는 이러한 많은 Api DLL 서버 로드 될 때 호출 됩니다 때문에 CoInitialize/CoInitializeEx를 호출 하지 않습니다. 따라서 DLL 서버 스레딩 모델 COM 시스템와 호환 되는 방식으로 작동 하는지 확인할 수 있도록 지 원하는 COM 알리기 위해 레지스트리를 사용 해야 합니다. ThreadingModel 구성 요소의 CLSID\InprocServer32 키의 명명 된 값은이 목적을 위해 다음과 같이 사용 됩니다.

  • ThreadingModel 값 없음: 단일 스레딩 모델을 지원 합니다.
  • ThreadingModel = 아파트: STA 지원 모델입니다.
  • ThreadingModel = 둘 다: 지원 STA 및 MTA 모델입니다.
  • ThreadingModel 무료 =: MTA만 지원 합니다.
참고: ThreadingModel InprocServer32 Win32 설명서의 일부 이전 버전에서으로 잘못 설명의 하위 키가 없는 명명된 된 값입니다.

-프로세서 서버 스레딩 모델이이 문서의 뒷부분에서 설명 합니다. In-proc 서버는 다양 한 유형의 (각각 자체 고유한 CLSID) 개체를 제공 하는 경우 각 유형에 다른 ThreadingModel 값을 가질 수 있습니다. 즉, 스레딩 모델이 아닙니다 CLSID를 당 당 코드 패키지/d l L. 그러나의 API 진입점 "부트스트랩" 하 고 모든 프로세서에서 서버를 조회 하는 데 필요한 (DLLGetClassObject(), DLLCanUnloadNow()) 이어야 합니다 스레드로부터 안전한 지 원하는 다중 스레드 프로시저에서 서버용 (ThreadingModel 값이 아파트를 의미, 또는 자유 ).

이전에 명시 된 독립 프로세스 서버 ThreadingModel 값을 사용 하 여 자체를 표시 하지 않음에 따라. 오히려, CoInitialize 또는 CoInitializeEx를 사용합니다. 독립 프로세스를 실행 해야 하는 DLL 기반 서버를 사용 하 여 COM "대리" 기능 (예: 시스템 제공 서로게이트 DLLHOST. EXE) DLL 기반 서버에 대 한 규칙을 따르십시오 이 경우 특별히 고려할 사항은 없으며 가지가 있습니다.

클라이언트와 개체 다른 스레딩 모델을 사용할 때

작업 중이 아닌 객체와 클라이언트 간의 상호 작용은도 서로 다른 프로세스에서 클라이언트와 개체는 COM 개체에 클라이언트에서 호출을 전달에 관련 된 것 이므로 다른 스레딩 모델을 사용할 때. COM 클라이언트와 서버 사이 존재가, 때문에 스레딩 모델을 상호 운용성을 위한 코드를 제공 합니다. 예를 들어, STA 개체를 STA 또는 MTA 여러 클라이언트가 동시에 호출 COM 서버의 메시지 큐에 해당 하는 창 메시지를 배치 하 여 호출을 동기화 합니다. 개체의 STA 한 번의 호출을 검색 하 고 메시지를 디스패치합니다 때마다 받습니다. 스레딩 모델이 상호 운용성 모든 조합은 허용 되며 클라이언트에서 작업 중이 아닌 객체와 완벽 하 게 지원 됩니다.

클라이언트 및 다른 스레딩 모델을 사용 하는 프로시저에 개체 간의 상호 작용 하는 것은 더 복잡 합니다. 서버 처리를 하지만 COM 해야 interpose 자체 클라이언트와 어떤 경우에는 개체입니다. 예를 들어, STA 모델을 지원 하도록 설계 된 프로시저의 개체 클라이언트의 여러 스레드에서 동시에 호출할 수 있습니다. COM 클라이언트가 스레드 개체는 이러한 동시 액세스가 설계 되지 않았습니다 때문에 개체의 인터페이스에 직접 액세스할 수 없습니다. 대신, COM 호출 동기화 되 고 연결 된 개체를 "포함" 하는 STA 스레드가 수행한 있어야 합니다. 추가 된 복잡성에도 불구 하 고 운용성 스레딩 모델의 모든 조합은 클라이언트와 개체 처리 허용 됩니다.

스레딩 모델에서 독립 프로세스 (EXE 기반) 서버

다음은 세 종류의 독립 프로세스 서버는 해당 클라이언트에서 사용 하는 스레딩 모델 관계 없이 모든 COM 클라이언트에서 사용할 수 있습니다.

  1. STA 모델 서버:

    서버에서 하나 이상의 Sta COM 작업을 수행합니다. 들어오는 호출 com 동기화 되 고 연결 된 개체가 만들어진 STA 스레드를 통해 배달 됩니다. 클래스 팩터리 메서드 호출은 클래스 팩토리가 등록 STA와 관련 된 스레드에 의해 배달 됩니다. 개체 및 클래스 팩터리 동기화를 구현할 필요는 없습니다. 그러나 해당 구현 자가 여러 Sta가 사용 되는 전역 변수에 대 한 액세스를 동기화 해야 합니다. 서버는 CoMarshalInterThreadInterfaceInStream와 CoGetInterfaceAndReleaseStream Sta 사이 다른 서버에서 가능한 인터페이스 포인터를 마샬링하는 데 사용 해야 합니다. 서버는 필요에 따라 구현할 수 있습니다. IMessageFilter 각 STA com 호출 전달의 여러 측면을 제어할 수 디 제너 레이트 경우는 하나의 STA.에 COM 작업을 수행 하는 단일 스레드 모델 서버
  2. MTA 모델 서버:

    서버가 모두 MTA에 속한 하나 이상의 스레드에서 COM 작업을 수행 합니다. 호출 하 여 동기화 되지 않은 클라이언트 호출이 이러한 스레드 중 하나에서 제공 하 고 COM. COM 서버 프로세스에서 스레드 풀을 만듭니다. 스레드를 검색 하 여 메시지를 발송할 필요가 없습니다. 개체 및 클래스 팩터리 동기화를 구현 해야 합니다. 서버는 스레드 간에 인터페이스 포인터를 마샬링할 필요가 없습니다.
  3. 혼합 된 모델 서버:

    이 문서 "혼합 스레딩 모델" 자세한 내용은 섹션을 참조 하십시오.

클라이언트 모델 스레딩

클라이언트의 세 가지 범주가 있습니다.

  1. STA 모델 클라이언트:

    클라이언트가 연결 된 하나 이상의 Sta 스레드에서 COM 작업을 수행 합니다. 클라이언트는 CoMarshalInterThreadInterfaceInStream 및 CoGetInterfaceAndReleaseStream Sta 간에 인터페이스 포인터를 마샬링하는 데 사용 해야 합니다. 디 제너 레이트 경우 하나의 STA.에 COM 작업을 수행 하는 단일 스레딩 모델 클라이언트 클라이언트의 스레드가 메시지 루프를 나가는 호출 하는 제공 하는 COM에 들어갑니다. 클라이언트는 IMessageFilter 콜백 및 호출 및 다른 동시성 문제를 나가는 기다리는 동안 처리가 창 메시지 관리할 수 사용할 수 있습니다.
  2. MTA 모델 클라이언트:

    클라이언트가 모두 MTA에 속한 하나 이상의 스레드에서 COM 작업을 수행 합니다. 클라이언트는 스레드 간에 인터페이스 포인터를 마샬링하는 데 필요 하지 않습니다. 클라이언트가 IMessageFilter를 사용할 수 없습니다. 클라이언트 스레드를 일시 중단 때 호출이 반환 될 때 이력서와 작업 중이 아닌 개체를 COM 호출 하는 것입니다. 들어오는 호출 COM 만들어지고 관리 되는 스레드에서 도착합니다.
  3. 혼합 된 모델 클라이언트:

    이 문서 "혼합 스레딩 모델" 자세한 내용은 섹션을 참조 하십시오.

(DLL 기반) 서버에서 프로세서의 모델 스레딩:

해당 클라이언트에서 사용 하는 스레딩 모델 관계 없이 모든 COM 클라이언트에서 사용할 수 있으며 각 proc에 서버의 네 가지 종류가 있습니다. 그러나 프로세서에서 서버 제공 마샬링 코드 구현 일반적으로 해당 COM 마샬링이 필요한 스레딩 모델의 상호 운용성을 지원 하려는 경우 사용자 지정 (비-시스템 정의) 인터페이스에 대해 클라이언트 간의 인터페이스 아파트입니다. 네 가지 범주는 다음과 같습니다.

  1. In-proc 서버를 지 원하는 스레드 STA (단일 "main")-ThreadingModel 값이 없습니다.

    이 서버에서 제공 하는 개체를 동일한 기준이 만들어진 클라이언트 STA 액세스할 수 필요 합니다. 또한 서버에 필요한 모든 진입점, DllGetClassObject 및 DllCanUnloadNow, 및 전역 데이터 (주 STA 함께 연결 된 하나) 동일한 스레드에서 액세스할 수 있습니다. 다중-에 COM 스레딩 도입 이전에 존재 하는 서버는이 종류에 있는.입니다. 이러한 서버의 COM 프로세스의 주 STA 서버가 제공 하는 모든 개체를 만들고 주 STA.와 관련 된 스레드에 의해 배달 되는 개체에 대 한 호출 여러 스레드에서 액세스할 수 설계 되지 않았습니다. 다른 클라이언트 아파트 프록시를 통해 개체에 대 한 액세스를 얻을 수 있습니다. 다른 아파트 호출의 (스레드 간 마샬링) 주 STA 스텁 및 개체 프록시의 이동합니다. 이 마샬링 COM 개체에 대 한 호출을 동기화 할 수 있으며 호출 개체가 만들어진 STA에 의해 배달 됩니다. 스레드 간 마샬링을 하므로이 서버 여러 Sta (범주 2) 지원 하도록 다시 작성할 좋습니다 직접 호출 하는 상대적으로 느립니다.
  2. ThreadingModel로 표시 된 프로세서에서 지 원하는 서버에는 단일 스레드 아파트 모델 (Sta 여러)-아파트 =.

    이 서버에서 제공 하는 개체를 동일한 기준이 만들어진 클라이언트 STA 액세스할 수 필요 합니다. 따라서 그는 단일 스레드 처리 서버에서 제공 하는 개체와 비슷합니다. 그러나이 서버에서 제공 하는 개체 서버가 DllGetClassObject, DllCanUnloadNow 및 다중 스레드 사용에 대 한 전역 데이터 등과 같은 진입점을 설계 해야 하므로 과정의 여러 Sta에 만들 수 있습니다. 예를 들어, 프로세스의 두 Sta 프로시저에서 개체의 인스턴스가 두 개를 동시에 만드는 경우 DllGetClassObject 호출할 수도 동시에 두 Sta. 마찬가지로, DllCanUnloadNow 코드는 서버에서 여전히 실행 되는 동안 언로드 중에서 서버를 보호 하도록 작성 되어야 합니다.

    서버에서 모든 개체를 만들려면 클래스 팩터리의 인스턴스를 하나만 제공 하는 경우 클래스 팩터리 구현도 설계 되어야 합니다 다중 스레드 사용에 대 한 여러 클라이언트 Sta 액세스할 수 있기 때문에. 서버가 DllGetClassObject 호출 될 때마다 클래스 팩토리의 새 인스턴스를 만들고, 클래스 팩터리 스레드로부터 안전한 것으로 필요가 없습니다. 그러나 구현자는 모든 전역 변수에 대 한 액세스를 동기화 해야 합니다.

    클래스 팩터리에서 만든 COM 개체를 스레드로부터 안전한 필요가 없습니다. 그러나 전역 변수의 액세스 구현자에 의해 동기화 되어야 합니다. 스레드에 의해 만들어진 개체가 항상 통해 액세스할 스레드 개체에 대 한 모든 호출에서 COM. 클라이언트 아파트 프록시를 통해 개체가 만들어진 STA 개체를 액세스 해야 하는 동기화 됩니다. 이러한 프록시 하는 경우 클라이언트에서 해당 아파트 간의 인터페이스를 마샬링합니다 만들어집니다.

    모든 클라이언트는 클래스 팩터리를 통해 STA 개체를 만든 개체에 대 한 직접적인 포인터를 가져옵니다. 이것은 다른 개체 단일 스레드 처리만 클라이언트의 주 STA 개체 및 개체 향상 액세스 프록시를 통해 개체를 만드는 다른 모든 Sta에 대 한 직접적인 포인터를 가져옵니다. 스레드 간 마샬링을 직접 전화 상대적으로 느린 이기 때문에 여러 Sta를 지 원하는 단일 스레드 처리 서버를 변경 하 여 속도 크게 향상 될 수 있습니다.
  3. ThreadingModel로 표시 된 프로세서에서 지 원하는 서버에만 MTA-= 있음:

    이 서버에서 제공 하는 개체를 mta에 안전 합니다. 자체 동기화 구현 하 고 여러 클라이언트 스레드에서 동시에 액세스 합니다. 이 서버가 STA 모델과 호환 되지 않는 문제가 있을 수 있습니다. (예를 들어, Windows 메시지 큐는 STA.의 메시지 펌프를 해제 하는 방식에서 사용)으로 또한 "자유"로 개체의 스레딩 모델을 표시 하 여 개체의 구현자는 내용의 다음:이 개체를 모든 클라이언트 스레드에서 호출할 수 있지만이 개체도 않고도 전달할 수 인터페이스 포인터 직접 (마샬링) 하는 스레드가 있는 것 생성 하 고 이러한 스레드가 이러한 포인터를 통해 호출을 만들 수 있습니다. 따라서이 개체 (싱크) 같은 클라이언트 구현 된 개체 인터페이스 포인터 전달 하는 클라이언트를 만든 모든 스레드에서이 인터페이스 포인터를 선택할 수 있습니다. 클라이언트가 STA 경우 싱크 개체를 만든 스레드에서 다른 스레드에서 직접 호출 오류 (위 2에서 설명) 하는 대로 됩니다. 따라서 COM 클라이언트에 연결 된 STA 스레드 프록시를 통해 개체를 처리의이 종류에 액세스할 수 있는 항상 보장 합니다. 또한 STA 스레드에서 직접 실행할 수 있도록 때문에 이러한 개체 자유 스레드된 마샬러를 사용 하 여 집계 하지 해야 합니다.
  4. ThreadingModel로 표시 된 프로세서에서 지 원하는 서버를 아파트 모델 및 자유 스레드-= 둘 다.

    이 서버에서 제공 하는 개체는 자체 동기화 구현 하 고 여러 클라이언트 아파트에서 동시에 액세스 하는. 또한이 개체가 만들어진 Sta 또는 MTA 클라이언트 프로세스에서 프록시를 통해 직접 대신에 사용 합니다. 이 개체를 Sta에 직접 사용 하기 때문에 서버 스레딩에 적합 한 방식으로 개체에 대 한 액세스의 보장 하므로 스레드 간에 다른 서버에서 가능한 경우 개체의 인터페이스 마샬링해야 합니다. 또한 "모두"로 개체의 스레딩 모델을 표시 하 여 개체의 구현자는 내용의 다음:이 개체를 모든 클라이언트 스레드에서 호출할 수 있지만이 개체에서 클라이언트 콜백을 있는 아파트에 대해서만 수행 됩니다 re 개체 ceived 콜백 개체에 대 한 인터페이스 포인터입니다. COM 개체를를 STA 클라이언트 프로세스의 MTA에서와 같이에서 직접 만들 수 있습니다.

    가져오기 때문에 항상 이러한 개체를 만드는 모든 아파트 프록시 포인터를 사용 하지 않고 직접 포인터, ThreadingModel "와" 개체 성능이 향상 ThreadingModel "자유" 개체는 STA.에 로드 될 때

    "모두" 개체는 ThreadingModel MTA 액세스 (이것은 완전히 스레드로부터 안전한 내부적으로)도 하므로, 성능 CoCreateFreeThreadedMarshaler 제공한 마샬러를 집계 하 여 속도 향상 시킬 수 있습니다. 모든 호출 개체에이 시스템 제공 개체 집계 및 사용자 지정 마샬링하는 프로세스의 모든 아파트에 개체에 대 한 포인터를 직접. 모든 아파트 클라이언트가 STA 또는 MTA는 액세스할 수 있습니다 다음 직접 아닌 개체 프록시를 통해. 예를 들어, STA 모델 클라이언트는 STA1의 프로시저에 개체를 만듭니다와 STA2 개체를 마샬링합니다. 자유 스레드 마샬러를 사용 하 여 개체를 집계 하지 않는, STA2 개체 프록시를 통해 액세스를 얻게 됩니다. 자유 스레드된 마샬러 STA2 개체에 대 한 직접적인 포인터를 제공 합니다.

    참고: 자유 스레드 마샬러를 사용 하 여 집계할 때 주의 해야 합니다. 예를 들어, "모두" (및 또한 자유 스레드 마샬러를 사용 하 여 집계) ThreadingModel로 표시 된 개체에 있는 ThreadingModel 인 "아파트"는 다른 개체에 대 한 인터페이스 포인터 데이터 멤버를 가정 합니다. 다음 가정 STA 첫 번째 개체를 만들고 생성 하는 동안 첫 번째 개체가 두 번째 개체를 만듭니다. 위에서 설명한 규칙에 따라 첫 번째 개체가 이제 보유 하 고 대 한 직접적인 포인터를 두 번째 개체를. 이제 해당 STA 다른 아파트 첫 번째 개체에 인터페이스 포인터를 마샬링합니다 가정 합니다. 자유-첫 번째 개체가 집계 스레드된 마샬러를 때문에 첫 번째 개체에 대 한 직접적인 포인터를 두 번째 아파트 지정 됩니다. 두 번째 아파트 다음이 포인터를 통해 호출 하 고이 호출 하면 첫 번째 개체가 두 번째 개체에 인터페이스 포인터를 통해 호출 하는 경우 다음 오류가 발생 했습니다, 두 번째 개체는 고려 하지 않은 두 번째에서 직접 호출할 수 있기 때문에 아파트입니다. 첫 번째 개체가 보유 하 고 포인터에 대 한 직접적인 포인터를 사용 하지 않고 두 번째 개체에 대 한 프록시를 이렇게 하면 다른 오류가 발생 하면. 하나의 아파트와 관련 된 COM 개체는 시스템 프록시 됩니다. 하는 추적 자신의 아파트 특정 circularities를 방지 하기 위해. 지금에 개체가 실행 중인 스레드가 아닌 다른 아파트 관련 된 프록시 호출 하는 개체 프록시의 RPC_E_WRONG_THREAD 반환 받습니다 한 호출이 실패 합니다.

모델의 상호 운용성 클라이언트와 in-process 개체를 스레딩

클라이언트 프로세스에서 개체와 스레딩 모델이 상호 운용성의 모든 조합이 허용 됩니다.

COM은 모든 STA 모델 클라이언트 및 클라이언트의 주 STA에 개체 액세스 만들고 STA [Ex] CoCreateInstance를 호출 하는 클라이언트에 게 마샬링 단일 스레드 프로시저에 개체와 상호 작용 합니다.

클라이언트의 MTA는 STA 모델 in-proc 서버를 만드는 경우 "호스트를" STA 클라이언트에서 COM 회전 합니다. 이 호스트 STA 개체를 생성 하 고 인터페이스 포인터를 MTA로 다시 마샬링됩니다. 마찬가지로, STA MTA in-proc 서버를 만들면 COM 작동 한 호스트 MTA 개체를 만들 및 단일 스레딩 모델과 MTA 모델 사이 STA. 상호 운용성 마샬링된 백 비슷하게 처리 하는 단일 스레드 모델 이기 때문에 STA 모델의 디 제너 레이트 서비스 케이스 뿐입니다.

마샬링 코드는 in-proc 서버에 필요한 클라이언트 아파트 간의 인터페이스를 마샬링할 COM 상호 운용성을 지원 하려는 경우 구현 하는 사용자 지정 인터페이스에 대 한 제공 되어야 합니다. 자세한 내용은 ' 참조 ' 절을 참조 하십시오.

스레딩 모델 및 반환 된 클래스 팩터리 개체 간의 관계

처리 서버 로드 되 고"로" 아파트의 정확한 정의 다음 두 단계에서 설명 되어 있습니다.

  1. -프로세서 서버 클래스를 포함 하는 DLL이 되지 않은 경우 이전에 로드 된 (프로세스 주소 공간으로 매핑하여) 운영 체제 로더에 의해 해당 작업이 수행 되 고 COM DLLGetClassObject 함수는 DLL에서 내보낸 주소를 가져옵니다. DLL 관련 된 모든 아파트 스레드에 의해 이미 로드 된,이 단계는 건너뜁니다.
  2. COM은 인터페이스를 사용 (또는 스레드 중 하나를 MTA의 경우) 필요한 클래스의 CLSID를 요청 하는 DLL에서 내보내는 DllGetClassObject 함수를 호출 하는 "로드" 아파트와 관련 된. 반환 된 팩터리 개체 개체 클래스의 인스턴스를 만드는 데 사용 됩니다.

    두 번째 단계 (com DllGetClassObject 호출) 클라이언트에서 CoGetClassObject/CoCreateIntance [Ex] 같은 아파트 내에서 호출 하는 각 시간에 발생 합니다. 즉, DllGetClassObject 호출할 수도 여러 번 동일한 아파트;와 관련 된 스레드 이것은 모두 해당 아파트에 있는 얼마나 많은 클라이언트가 해당 클래스에 대해 클래스 팩터리 개체에 액세스 하려고 하는.
클래스 구현을 제작자 및 궁극적으로 지정한 클래스의 DLL 패키지 만든이 자유롭게 DllGetClassObject 함수 호출에 대 한 응답으로 반환 하려면 어떤 팩터리 개체를 결정 하는. DLL 패키지 만든이가 최종적으로 결정 한다는 코드 "숨김" DLL 전체 DllGetClassObject() 단일 진입점은 어떤 권한이 첫번째와 마지막 잠재적으로 수행할 작업을 결정 합니다. 세 가지 일반적인 가능성은.

  1. DllGetClassObject 호출 스레드 (즉 STA 당 하나의 클래스 팩터리 개체를 MTA 내에서 잠재적으로 여러 개의 클래스 팩터리) 당 고유 클래스 팩터리 개체를 반환 합니다.
  2. DllGetClassObject 호출 스레드 또는 호출 스레드와 관련 된 아파트의 종류에 관계 없이 동일한 클래스 팩터리 개체를 항상 반환 합니다.
  3. DllGetClassObject 호출 아파트 (STA 및 MTA를 모두에서 아파트 마다 하나씩) 당 고유 클래스 팩터리 개체를 반환합니다.
DllGetClassObject 호출 하 고 (예: 전화 DllGetClassObject 새 클래스 팩터리 개체) 실제로 반환 된 클래스 팩터리 개체 간의 관계에 대 한 다른 가능성 있지만 유용한 현재 표시 되지 않습니다.

클라이언트와 서버 프로세서에 대 한 스레딩 모델 개체의 요약

다음 표에서 경우는 클라이언트 스레드 호출 CoGetClassObject 처리 서버로 구현 되는 클래스에 다른 스레딩 모델 간의 상호 작용을 요약 합니다.

클라이언트/스레드 종류:

  • 관련 된 "기본" STA 스레드에서 실행 되는 클라이언트 (COINIT_APARTMENTTHREADED 플래그로 CoInitialize 또는 CoInitializeEx를 호출 하려면 먼저 스레드)-(단일 스레딩 모델)이이 STA0를 호출 합니다.
  • 클라이언트에서에서 실행 되 고 [ASCII 150] STA 호출에 관련 된 스레드에 STA *이.
  • 클라이언트는 MTA에서 연결 된 스레드에서 실행 중입니다.
DLL 서버의 종류:

  • 서버 키가 없는 ThreadingModel-이 메서드를 호출 "없음."
  • 서버는 "아파트" 표시-이 "Apt."를 호출 합니다.
  • 서버는 "무료." 표시
  • 서버는 표시 "모두".
아래 표를 읽을 때 염두에 위에서 만든 정의 하는 서버를 아파트에 "로드"입니다.

Client Server Result
------ ------ -----------------------------------------
STA0 None Direct access; server loaded into STA0
STA* None Proxy access; server loaded into
STA0.
MTA None Proxy access; server loaded into STA0; STA0 created
automatically by COM if necessary;
STA0 Apt Direct access; server loaded into STA0
STA* Apt Direct access; server loaded into STA*
MTA Apt Proxy access; server loaded into an
STA created automatically by COM.
STA0 Free Proxy access; server is loaded into MTA
MTA created automatically by COM if necessary.
STA* Free Same as STA0->Free
MTA Free Direct access
STA0 Both Direct access; server loaded into STA0
STA* Both Direct access; server loaded into STA*
MTA Both Direct access; server loaded into the MTA

참조


SDK 설명서에서 CoRegisterMessageFilter() 및 IMessageFilter 인터페이스입니다.

자세한 내용은 Microsoft 기술 자료의 다음 문서를 참조 하십시오.
136885 OLE 스레드 메시지 발송 되어야
아파트 모델 클라이언트 137629 in-proc 개체 사용자 지정 인터페이스