문제

올에 무엇이 보이는 첫눈에 좋아하는 MT 문제이지만,내가 이해하려고 노력하고 세부 사항에서 STA 모델을 사용하여 COM+.

효과적으로,기존 COM+구성 요소로 작성 VB6,는 전화로 native(i.e.,지-COM)Win32DLL C++로 작성되었습니다.

을 움직여보고(과가 재현하 테스트에서는)문제는 그것으로,나는 추가 코드를 디버깅하는 무슨 일이 있었는지 알아보십시에서 발견되는 경우 문제가 발생했 로그 메시지를 인터리브에서 파일 그래서 그것을 암시하는 DLL 을 호출되는 것에 의해 두 개의 스레드 한 번에.

지금은 로깅가별 스레드에 따라 파일 _getpid()및 GetCurrentThreadId(),그래서 그것은 보인다면 코드에서는 C++DLL 을 호출하고,그것을 얻기라고 두 번 같은 스레드에서 동일한 시간입니다.내의 이해 STA 말한다 제안이 될 수 있는 경우 COM 마샬 각각의 인스턴스의 개체로서 하나의 스레드를 일시 중단하고 재시작에서 실행됩니다.

Unfortuantly 난 어디로 가서 여기입니다.나는 내가 호출 CoInitialiseEx()에 DllMain()을 말 COM 이 STA DLL 지만,다른 곳은 이에 대해서만 유효 COM Dll 및 영향을 미치지 않습니다 기본 DLL.다른 옵션은 부품의 DLL 으로 중요한 부분에 대한 액세스 직렬화를(가 어떤 충격 성능에 가지고 있는 턱).

수도 재 DLL,그러나 없 공유 상태 또는 글로벌 vars-모든 지역 변수에 너무 이론에서는 각 통화를 얻는 자체 스택,하지만 내가 궁금하는 경우 STA 모델은 기본적으로 갖는 몇 가지 이상한 효과에이고 재입력으로 로드되 DLL 에서 같은 입국 지점으로 또 다른 호출합니다.Unfortuantly,내가 알지 못하는 방법 증명 테스트 또는 이론이다.

질문에 기본적으로:

  1. 때 STA COM+구성 요소의 전화를 기본 DLL,거기에 아무것도 STA 모델 을 방지 활성"실"일시 중단하고 제어 전달되는 다른"실"의 중간에 DLL 호?
  2. 은 CoInitialiseEx()다른 방법으로 이 문제를 해결하기 위해 또는지?
  3. 지 않은 경우(1)or(2)은"좋은"가정은 무엇일까요?
도움이 되었습니까?

해결책

아파트 스레드 COM 서버에서 COM 클래스의 각 인스턴스는 단일 스레드로 액세스 할 수 있습니다. 이것은 의미합니다 인스턴스 스레드 안전합니다. 그러나 다른 스레드를 사용하여 많은 인스턴스를 동시에 만들 수 있습니다. 이제 COM 서버에 관한 한, 기본 DLL은 특별한 일을 할 필요가 없습니다. 모든 실행 파일에서 사용되는 Kernel32.dll에 대해 생각해보십시오. COM 서버에서 사용하면 COM이 초기화됩니까?

DLL 관점에서 다른 인스턴스가 동시에 전화 할 수 있으므로 스레드 안전을 유지해야합니다. STA는이 사건에 대해 귀하를 보호하지 않습니다. 당신은 당신이 글로벌 변수를 사용하지 않는다고 말하기 때문에, 나는 문제가 다른 곳에 있다고 가정 할 수 있으며, com을 가리키는 것처럼 보이는 상황에 대해서만 보여줍니다. 평범한 오래된 C ++ 메모리 문제가 없다고 확신하십니까?

다른 팁

내가 심는 당신의 문제는 깊은 곳에서라 DLL,그것이 만들어 아웃바운드 COM 호출을 다른 아파트(또 다른 스레드에서 동일한 프로세스,또는 객체에 MTA,또는 다른 프로세스에 전적으로).COM 허가 STA 스레드의 결과를 기다리고 아웃바운드 통화를 받는 또 다른 인바운드 통화,재귀적으로 처리.그것은 의도만을 위해 지속적인 대화를 통해 사이 동일한 개체-즉전 B B 통화시,전 B 에 다시 다시-그러나 전화를 받을 수 있에서 다른 물체를 한 경우 나눠주는 인터페이스 포인터를 여러 클라이언트,클라이언트는 공유 인터페이스 포인터를 다른 클라이언트입니다.일반적으로 그것은 나쁜 생각하 손으로 인터페이스 포인터를 하나의 스레드 개체 여러 쓰레드는 클라이언트들만을 기다려야 한다.만들자 스레드당 개체.

COM 일시 중단할 수 없습니다 다시 실행에서 어떤 쓰레드-새 수신 통화에 STA 스레드 수를 통해 도착하는 메시지 펌프입니다.을 때'차단'응답을 기다리,STA 스레드가 실제로 펌프,메시지를 확인하는 메시지와 함께 필터링(볼 IMessageFilter)는지 여부를 메시지를 처리할 수 있습니다.그러나 메시지 처리기해 나가는 새로운 호출하는 경우 그들 COM 반환됩니다 RPC_E_CANTCALLOUT_INEXTERNALCALL 오류가("는 것은 불법을 내부에 있는 동안 메시지를 필터링합니다.")

유사한 문제가 발생할 수 있습니다 만약 당신이 메시지 펌프(GetMessage/DispatchMessage)이내에서는 네이티브 DLL.내가 문제가 있었 VB 의 DoEvents 인터페이스에서 절차가 있습니다.

CoInitializeEx 해서만 호출할 수 있의 창조자에 의해 실기 때문에,단지 그들은 알고 무엇이 자신의 메시지 펌핑 행동이 될 것입니다.그것은 가능성이 있는 경우 호출하 DllMain 에서 그것은 단순히 실로 당신의 기본 DLL 을 호출에 응답하 COM 화,그래서 손님이 있어야 합 궁극적으로 소 CoInitializeEx 에서 실을 만들기 위해 호출합니다.에 DLL_THREAD_ATTACH 알림한 새로 생성된 스레드,작동 수 있습니다 표면적으로 하는 프로그램을 발생해 오작동하는 경우 COM 블록을 할 때 그것은 펌프 그 반대의 경우도 마찬가지입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top