Flertrådade lägenheter
I en flertrådad lägenhetsmodell finns alla trådar i processen som har initierats som fritrådade i en enda lägenhet. Därför behöver du inte konvertera mellan trådar. Trådarna behöver inte hämta och skicka meddelanden eftersom COM inte använder fönstermeddelanden i den här modellen.
Anrop till metoder för objekt i den flertrådade lägenheten kan köras på vilken tråd som helst i lägenheten. Det finns ingen serialisering av anrop. många anrop kan ske till samma metod eller till samma objekt samtidigt. Objekt som skapas i den flertrådade lägenheten måste kunna hantera anrop på sina metoder från andra trådar när som helst.
Eftersom anrop till objekt inte serialiseras på något sätt ger samtidighet för flertrådade objekt högsta prestanda och utnyttjar den bästa fördelen med maskinvara för flera processorer för korstråds-, korsprocess- och korsdatorsamtal. Det innebär dock att koden för objekt måste tillhandahålla synkronisering i sina gränssnittsimplementeringar, vanligtvis med hjälp av synkroniseringsprimitiver, till exempel händelseobjekt, kritiska avsnitt, mutex eller semaforer, som beskrivs senare i det här avsnittet. Eftersom objektet inte styr livslängden för de trådar som kommer åt det, kan inget trådspecifikt tillstånd lagras i objektet (i trådlokal lagring).
Följande är några viktiga överväganden när det gäller synkronisering för flertrådade lägenheter:
- COM tillhandahåller samtalssynkronisering endast för entrådade lägenheter.
- Flertrådade lägenheter tar inte emot samtal när de ringer samtal (i samma tråd).
- Flertrådade lägenheter kan inte göra indatasynkroniseringsanrop.
- Asynkrona anrop konverteras till synkrona anrop i flertrådade lägenheter.
- Meddelandefiltret anropas inte för någon tråd i en flertrådad lägenhet.
Om du vill initiera en tråd som fritrådad anropar du CoInitializeExoch anger COINIT_MULTITHREADED. Information om processervertrådning finns i In-Process servertrådsproblem.
Flera klienter kan samtidigt anropa, från olika trådar, ett objekt som stöder fri trådning. I fritrådade out-of-process-servrar skapar COM, via RPC-undersystemet, en pool med trådar i serverprocessen och ett klientanrop (eller flera klientanrop) kan levereras av någon av dessa trådar när som helst. En out-of-process-server måste också implementera synkronisering i sin klassfabrik. Objekt med fri tråd kan ta emot direkta anrop från flera trådar i klienten.
Klienten kan utföra COM-arbete i flera trådar. Alla trådar tillhör samma flertrådade lägenhet. Gränssnittspekare skickas direkt från tråd till tråd i en flertrådad lägenhet, så gränssnittspekare konverteras inte mellan trådarna. Meddelandefilter (implementeringar av IMessageFilter) används inte i flertrådade lägenheter. Klienttråden pausas när den gör ett COM-anrop till objekt som inte finns i lägenheten och återupptas när anropet returneras. Anrop mellan processer hanteras fortfarande av RPC.
Trådar som initieras med den fritrådade modellen måste implementera sin egen synkronisering. Som vi nämnde tidigare i det här avsnittet aktiverar Windows den här implementeringen via följande synkroniseringsprimitiver:
- Händelseobjekt ger ett sätt att signalera en eller flera trådar om att en händelse har inträffat. Alla trådar i en process kan skapa ett händelseobjekt. En referens till händelsen returneras av den händelseskapande funktionen CreateEvent. När ett händelseobjekt har skapats kan trådar med ett handtag till objektet vänta på det innan körningen fortsätter.
- Viktiga avsnitt används för ett kodavsnitt som kräver exklusiv åtkomst till en uppsättning delade data innan de kan köras och som endast används av trådarna i en enda process. Ett kritiskt avsnitt är som ett vändkors genom vilket endast en tråd i taget kan passera, vilket fungerar på följande sätt:
- För att säkerställa att inte fler än en tråd i taget får åtkomst till delade data allokerar en processs primära tråd en global CRITICAL_SECTION datastruktur och initierar dess medlemmar. En tråd som anger ett kritiskt avsnitt anropar funktionen EnterCriticalSection och ändrar datastrukturens medlemmar.
- En tråd som försöker ange ett kritiskt avsnitt anropar EnterCriticalSection som kontrollerar om CRITICAL_SECTION datastrukturen har ändrats. I så fall finns en annan tråd för närvarande i det kritiska avsnittet och den efterföljande tråden förs i viloläge. En tråd som lämnar ett kritiskt avsnitt anropar LeaveCriticalSection, som återställer datastrukturen. När en tråd lämnar ett kritiskt avsnitt vaknar systemet en av de vilande trådarna, som sedan går in i det kritiska avsnittet.
- Mutexes utför samma funktion som ett kritiskt avsnitt, förutom att mutex är tillgängligt för trådar som körs i olika processer. Att äga ett mutexobjekt är som att ha ordet i en debatt. En process skapar ett mutex-objekt genom att anropa funktionen CreateMutex, som returnerar ett handtag. Den första tråden som begär ett mutex-objekt hämtar ägarskapet för det. När tråden har slutförts med mutex skickas ägarskapet till andra trådar enligt först till kvarn-principen.
- Semaforer används för att upprätthålla ett referensantal för vissa tillgängliga resurser. En tråd skapar en semafor för en resurs genom att anropa funktionen CreateSemaphore och skicka en pekare till resursen, ett initialt resursantal och det maximala resursantalet. Den här funktionen returnerar ett handtag. En tråd som begär en resurs skickar semaforreferensen i ett anrop till funktionen WaitForSingleObject. Semaforobjektet avsöker resursen för att avgöra om den är tillgänglig. I så fall minskar semaforen resursantalet och aktiverar den väntande tråden. Om antalet är noll förblir tråden i viloläge tills en annan tråd släpper en resurs, vilket gör att semaforen ökar antalet till en.
Relaterade ämnen
-
Single-Threaded och för flertrådad kommunikation