Multithreaded Appartementen
In een multithreaded appartementsmodel bevinden alle threads in het proces dat als vrije thread is geïnitialiseerd, zich in één appartement. Daarom is het niet nodig om marshal tussen threads. De threads hoeven geen berichten op te halen en te verzenden omdat COM geen vensterberichten in dit model gebruikt.
Aanroepen naar methoden van objecten in het multithreaded appartement kunnen worden uitgevoerd op elke thread in het appartement. Er is geen serialisatie van aanroepen; er kunnen veel aanroepen worden uitgevoerd op dezelfde methode of op hetzelfde object tegelijk. Objecten die zijn gemaakt in het multithreaded appartement moeten op elk gewenst moment aanroepen van andere threads kunnen verwerken.
Omdat aanroepen naar objecten op geen enkele manier worden geserialiseerd, biedt multithreaded object gelijktijdigheid de hoogste prestaties en profiteert het beste van multiprocessorhardware voor crossthread- en cross-process- en cross-machine-aanroepen. Dit betekent echter dat de code voor objecten synchronisatie moet bieden in hun interface-implementaties, meestal door gebruik te maken van synchronisatieprimitief zoals gebeurtenisobjecten, kritieke secties, mutexes of semaphores, die verderop in deze sectie worden beschreven. Bovendien, omdat het object de levensduur van de threads die er toegang toe hebben, niet bepaalt, kan er geen threadspecifieke status worden opgeslagen in het object (in lokale threadopslag).
Hieronder volgen enkele belangrijke overwegingen met betrekking tot synchronisatie voor multithreaded appartementen:
- COM biedt alleen gesprekssynchronisatie voor appartementen met één thread.
- Multithreaded appartementen ontvangen geen oproepen tijdens het bellen (op dezelfde thread).
- Multithreaded appartementen kunnen geen ingevoerde gesprekken voeren.
- Asynchrone oproepen worden geconverteerd naar synchrone oproepen in multithreaded appartementen.
- Het berichtfilter wordt niet aangeroepen voor een thread in een multithreaded appartement.
Als u een thread wilt initialiseren als vrije thread, roept u CoInitializeExaan en geeft u COINIT_MULTITHREADED op. Zie In-Process Server Threading Issuesvoor meer informatie over in-process serverthreading.
Meerdere clients kunnen tegelijk aanroepen vanuit verschillende threads, een object dat ondersteuning biedt voor gratis threading. In free-threaded out-of-process servers, COM, via het RPC-subsysteem, maakt u een groep threads in het serverproces en kan een clientoproep (of meerdere clientoproepen) op elk gewenst moment worden geleverd door een van deze threads. Een out-of-process-server moet ook synchronisatie in de klassefactory implementeren. Met vrije threads kunnen in-process-objecten directe aanroepen van meerdere threads van de client worden ontvangen.
De client kan COM in meerdere threads uitvoeren. Alle threads behoren tot hetzelfde multithreaded appartement. Interfacepointers worden rechtstreeks van thread naar thread doorgegeven binnen een appartement met meerdere threads, zodat interfacepointers niet tussen de threads worden geslepen. Berichtfilters (implementaties van IMessageFilter) worden niet gebruikt in multithreaded appartementen. De clientthread wordt onderbroken wanneer er een COM-oproep wordt uitgevoerd naar buiten-appartementsobjecten en wordt hervat wanneer de oproep terugkeert. Aanroepen tussen processen worden nog steeds verwerkt door RPC.
Threads die zijn geïnitialiseerd met het gratis threaded model, moeten hun eigen synchronisatie implementeren. Zoals eerder vermeld in deze sectie, maakt Windows deze implementatie mogelijk via de volgende synchronisatie primitiefen:
- Gebeurtenisobjecten bieden een manier om een of meer threads te signaleren die een gebeurtenis heeft plaatsgevonden. Elke thread binnen een proces kan een gebeurtenisobject maken. Een ingang naar de gebeurtenis wordt geretourneerd door de functie voor het maken van gebeurtenissen CreateEvent. Zodra een gebeurtenisobject is gemaakt, kunnen threads met een ingang naar het object wachten voordat de uitvoering wordt voortgezet.
- Kritieke secties worden gebruikt voor een codesectie waarvoor exclusieve toegang tot een aantal gedeelde gegevens is vereist voordat deze kan worden uitgevoerd en die alleen wordt gebruikt door de threads binnen één proces. Een kritieke sectie is als een draailijn waardoor slechts één thread tegelijk kan worden doorgegeven. Dit werkt als volgt:
- Om ervoor te zorgen dat niet meer dan één thread tegelijk toegang heeft tot gedeelde gegevens, wijst de primaire thread van een proces een globale CRITICAL_SECTION gegevensstructuur toe en initialiseert de leden ervan. Een thread die een kritieke sectie invoert, roept de EnterCriticalSection functie aan en wijzigt de leden van de gegevensstructuur.
- Een thread die probeert een kritieke sectie in te voeren, roept EnterCriticalSection aan die controleert of de CRITICAL_SECTION gegevensstructuur is gewijzigd. Zo ja, dan bevindt een andere thread zich momenteel in de kritieke sectie en wordt de volgende thread in de slaapstand gezet. Een thread die een kritieke sectie verlaat, roept LeaveCriticalSectionaan, waarmee de gegevensstructuur opnieuw wordt ingesteld. Wanneer een thread een kritieke sectie verlaat, ontwaakt het systeem een van de slaapthreads, die vervolgens de kritieke sectie binnenkomt.
- Mutexes voert dezelfde functie uit als een kritieke sectie, behalve dat de mutex toegankelijk is voor threads die in verschillende processen worden uitgevoerd. Het bezitten van een mutex-object is net als het hebben van de vloer in een debat. Een proces maakt een mutex-object door de functie CreateMutex aan te roepen, die een ingang retourneert. De eerste thread die een mutex-object aanvraagt, krijgt het eigendom ervan. Wanneer de thread is voltooid met de mutex, wordt het eigendom doorgegeven aan andere threads op basis van de eerste maalde, eerste maalde.
- Semaphores worden gebruikt voor het onderhouden van een referentieaantal op een aantal beschikbare resources. Een thread maakt een semaphore voor een resource door de functie CreateSemaphore aan te roepen en een aanwijzer door te geven aan de resource, het aantal initiële resources en het maximumaantal resources. Deze functie retourneert een ingang. Een thread die een resource aanvraagt, geeft de emafore-ingang door in een aanroep naar de WaitForSingleObject functie. Het object semaphore peilt de resource om te bepalen of het beschikbaar is. Zo ja, dan wordt het aantal resources afgebouwd en wordt de wachtthread geactiveerd. Als het aantal nul is, blijft de thread in de slaapstand totdat een andere thread een resource vrijgeeft, waardoor de reemafore het aantal naar één kan verhogen.
Verwante onderwerpen