다중 스레드 아파트

다중 스레드 아파트 모델에서 자유 스레드로 초기화 된 프로세스의 모든 스레드는 단일 아파트에 상주 합니다. 따라서 스레드 간에 마샬링할 필요가 없습니다. COM은이 모델에서 창 메시지를 사용 하지 않으므로 스레드에서 메시지를 검색 하 고 디스패치할 필요가 없습니다.

다중 스레드 아파트에서 개체의 메서드를 호출 하는 것은 아파트의 모든 스레드에서 실행할 수 있습니다. 호출을 직렬화 하는 것은 아닙니다. 동일한 메서드나 동일한 개체에 대 한 많은 호출이 동시에 발생할 수 있습니다. 다중 스레드 아파트에서 만든 개체는 언제 든 지 다른 스레드에서 해당 메서드에 대 한 호출을 처리할 수 있어야 합니다.

개체에 대 한 호출은 어떤 방식으로든 serialize 되지 않으므로 다중 스레드 개체 동시성은 가장 높은 성능을 제공 하 고 크로스 스레드, 크로스 프로세스 및 시스템 간 호출을 위해 다중 프로세서 하드웨어를 가장 효율적으로 활용 합니다. 그러나이는 일반적으로이 단원의 뒷부분에서 설명 하는 이벤트 개체, 임계 영역, 뮤텍스 또는 세마포와 같은 동기화 기본 형식을 사용 하 여 개체에 대 한 코드가 인터페이스 구현에서 동기화를 제공 해야 함을 의미 합니다. 또한 개체는 해당 개체에 액세스 하는 스레드의 수명을 제어 하지 않으므로 스레드 전용 상태를 개체 (스레드 로컬 저장소)에 저장할 수 없습니다.

다음은 다중 스레드 아파트 동기화와 관련 된 몇 가지 중요 한 고려 사항입니다.

  • COM은 단일 스레드 아파트에 대해서만 호출 동기화를 제공 합니다.
  • 동일한 스레드에서 호출을 수행 하는 동안 다중 스레드 아파트에서 호출을 받지 않습니다.
  • 다중 스레드 아파트는 입력 동기화 된 호출을 수행할 수 없습니다.
  • 비동기 호출은 다중 스레드 아파트에서 동기 호출로 변환 됩니다.
  • 다중 스레드 아파트의 스레드에 대해 메시지 필터가 호출 되지 않습니다.

스레드를 자유 스레드로 초기화 하려면 COINIT 다중 스레드를 지정 하 여 CoInitializeEx를 호출 _ 합니다. In-process 서버 스레딩에 대 한 자세한 내용은 In-process 서버 스레딩 문제를 참조 하세요.

여러 클라이언트는 자유 스레드를 지 원하는 개체를 사용 하 여 서로 다른 스레드에서 동시에 호출할 수 있습니다. 자유 스레드된 in-process 서버에서 COM은 RPC 하위 시스템을 통해 서버 프로세스에서 스레드 풀을 만들며 클라이언트 호출 (또는 다중 클라이언트 호출)은 언제 든 지 이러한 스레드 중 하나를 통해 전달 될 수 있습니다. 또한 out-of-process 서버는 해당 클래스 팩터리에서 동기화를 구현 해야 합니다. 자유 스레드된 in-process 개체는 클라이언트의 여러 스레드에서 직접 호출을 받을 수 있습니다.

클라이언트는 여러 스레드에서 COM 작업을 수행할 수 있습니다. 모든 스레드가 동일한 다중 스레드 아파트에 속합니다. 인터페이스 포인터는 다중 스레드 아파트 내의 스레드 간에 직접 전달 되므로 인터페이스 포인터가 해당 스레드 간에 마샬링되지 않습니다. 메시지 필터 ( imessagefilter.prefiltermessage의 구현)는 다중 스레드 아파트에서 사용 되지 않습니다. 클라이언트 스레드는 아파트 외부 개체에 대 한 COM 호출을 수행 하 고 호출이 반환 될 때 다시 시작 될 때 일시 중단 됩니다. 프로세스 간의 호출은 RPC에서 계속 처리 됩니다.

자유 스레드 모델로 초기화 된 스레드는 자체 동기화를 구현 해야 합니다. 이 섹션의 앞부분에서 설명한 것 처럼 Windows에서는 다음 동기화 기본 형식을 통해이 구현을 사용 하도록 설정 합니다.

  • 이벤트 개체는 이벤트가 발생 한 하나 이상의 스레드에 신호를 보내는 방법을 제공 합니다. 프로세스 내의 모든 스레드에서는 이벤트 개체를 만들 수 있습니다. 이벤트에 대 한 핸들은 이벤트 생성 함수인 CreateEvent에서 반환 됩니다. 이벤트 개체를 만든 후에는 개체에 대 한 핸들이 있는 스레드가 실행을 계속 하기 전에 기다릴 수 있습니다.
  • 중요 섹션은 일부 공유 데이터 집합에 대 한 단독 액세스를 필요로 하는 코드 섹션에 사용 되며,이를 실행 하려면 단일 프로세스 내의 스레드에서만 사용 됩니다. 중요 한 섹션은 한 번에 하나의 스레드만 통과 하 여 다음과 같이 작업 하는 회전식과 비슷합니다.
    • 한 번에 둘 이상의 스레드가 공유 데이터에 액세스 하지 않도록 하기 위해 프로세스의 기본 스레드는 전역 임계 _ 영역 데이터 구조를 할당 하 고 해당 멤버를 초기화 합니다. 임계 영역을 입력 하는 스레드는 EnterCriticalSection 함수를 호출 하 고 데이터 구조체의 멤버를 수정 합니다.
    • 임계 영역을 시작 하려고 하는 스레드는 EnterCriticalSection 을 호출 하 여 임계 _ 영역 데이터 구조가 수정 되었는지 여부를 확인 합니다. 그렇다면 다른 스레드가 현재 임계 영역에 있고 후속 스레드가 절전 모드로 전환 됩니다. 임계 영역을 종료 하는 스레드는 데이터 구조를 다시 설정 하는 LeaveCriticalSection를 호출 합니다. 스레드가 임계 영역을 벗어나면 시스템은 절전 모드 스레드 중 하나를 해제 하 고이를 임계 영역에 입력 합니다.
  • 뮤텍스는 다른 프로세스에서 실행 되는 스레드에 액세스할 수 있다는 점을 제외 하 고 임계 섹션과 동일한 기능을 수행 합니다. 뮤텍스 개체를 소유 하는 것은 토론에 바닥을 포함 하는 것과 같습니다. 프로세스는 핸들을 반환 하는 createmutex가 함수를 호출 하 여 뮤텍스 개체를 만듭니다. 뮤텍스 개체를 요청 하는 첫 번째 스레드는 해당 개체의 소유권을 가져옵니다. 스레드가 뮤텍스를 사용 하 여 완료 되 면 소유권은 첫 번째로 제공 되는 첫 번째 제공 방식으로 다른 스레드에 전달 됩니다.
  • 세마포는 사용 가능한 일부 리소스에 대 한 참조 횟수를 유지 관리 하는 데 사용 됩니다. 스레드는 Createsemaphore 함수를 호출 하 고 리소스에 대 한 포인터, 초기 리소스 수 및 최대 리소스 수를 전달 하 여 리소스에 대 한 세마포를 만듭니다. 이 함수는 핸들을 반환 합니다. 리소스를 요청 하는 스레드는 WaitForSingleObject 함수 호출에서 해당 세마포 핸들을 전달 합니다. 세마포 개체는 리소스를 폴링하여 사용할 수 있는지 여부를 확인 합니다. 그렇다면 세마포는 리소스 수를 감소 시키고 대기 중인 스레드를 절전 모드에서 해제 합니다. 개수가 0 인 경우 다른 스레드가 리소스를 해제할 때까지 스레드가 절전 상태로 유지 되므로 세마포가 카운트를 1 씩 증가 시킵니다.

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

스레딩 모델 선택

In-process 서버 스레딩 문제

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

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

단일 스레드 아파트