|
written by T. Schmidt |
|||||||||||||||||||||
|
||||||||||||||||||||||
|
Ein entscheidender Aspekt der Programmentwicklung mittels COM-Objekten ist die Art des Prozesses in dem ein COM-Objekt ausgeführt wird. COM Objekte werden von Threads instanziiert, Threads werden in Apartments ausgeführt und Apartments werden in einem Prozess ausgeführt. Das COM Threading ModellJedes Programm welches COM Objekte verwendet muß dem COM Laufzeitmodul mitteilen auf welcher Art es threading verwalten kann. Man unterscheidet drei Thread Modelle. 1. Single Thread ModellDas Programm teilt dem COM Laufzeitmodul mit, es kommuniziert mit Ihm mit nur einem ausführbaren Thread. Das bedeutet für das COM Objekt es verwaltet Methodenaufrufe hintereinander (seriell) im Haupttread des Programms. 2. Single-threaded Apartment Model (STA)Bei diesem Modell haben COM Objekte die Möglichkeit in verschiedenen Apartments mit dem Programm zu kommunizieren. Jedes Apartment enthält dabei genau einen Thread. Apartments bezeichnen genau definierte Regeln wie COM Objekte und Threads miteinander kommunizieren. Zur vereinfachten Anschauung bezeichnen Wir ein Apartment als quasi virtuellen Container in dem sich das COM Objekt und der dazugehörige Thread befindet. Jeder Thread eines Programms der COM Objekte benutzt, muß zuerst ein Apartment initialisieren, um dem COM Laufzeitmodul mittzuteilen, wie COM intern mit dem Thread kommunizieren kann. Wollen verschiedene Threads auf ein COM Objekt zugreifen, muss das COM Laufzeitmodul sicherstellen können, das das Objekt entsprechend den festgelegten Regeln des Apartments in dem es sich befindet verwendet wird. Methodenaufrufe an ein COM Objekt, welches zu einem Apartment gehört, werden seriell ausgeführt, egal von welchem Thread aus der Methodenaufruf erfolgte. Der Unterschied zum single-thread Modell ist die Möglichkeit mehrere Threads zu initialisieren, jeder in seinem Apartment. 3. Multi-threaded Apartment Modell (MTA)In einem Multithreaded Apartment können im Gegensatz zum STA mehrere Threads instanziiert sein. Wird ein COM Objekt in einem MTA instanziiert, stellt das COM Laufzeitmodul sicher, das eingehende Methodenaufrufe zu diesem Objekt gleichzeitig in verschiedenen Threads erfolgen können. COM Objekte in einem MTA müssen sicherstellen das sie eingehende Methodenaufrufe von jedem Thread und zu jeder Zeit gleichzeitig verwalten können. Sie müssen ihre (Daten)-Integrität bewahren können, welches auch als Threadsave bezeichnet wird.
Um eine Kommunikation mit verschiedenen COM Objekten zu ermöglichen, müssen beide das gleiche Threadmodell verwenden. Verwenden die Objekte verschiedene Threadmodelle, ist es die Aufgabe vom COM Laufzeitmodul ein einheitliches Modell zwischen den Objekten zu vereinbaren. Tabelle 1.1 zeigt die verschiedenen möglichen inkompatiblen Arten der Threadmodelle und das Resultierende vom COM Laufzeitmodul zur Kommunikation zwischen Client und Serveranwendung verwendete Threadmodell.
Tabelle 1.1 Das STA Modell ermöglicht es Multithreaded COM Programme zu entwickeln, wobei jeder Thread in seinem eigenen Apartment initialisiert wird. Damit dieser Thread mit dem COM Laufzeitmodul korrekt kommunizieren kann, muss er ein Apartment initialisieren. Wie aber initialisiert ein Thread ein STA? Mittels des API Aufrufes CoInitializeEx oder CoInitialize, welcher eine frühere Implementation ist. (CoInitializeEx setzt NT4 DCOM Erweiterungen voraus.) Soll ein STA instanziiert werden, der COM Objekte enthält auf die von verschiedenen Threads aus zugegriffen werden soll, dann muss dieser STA ein MessagePool einrichten. Das COM Laufzeitmodul übersetzt eingehende Methodenaufrufe in Windowsmessages und stellt diese in den Pool, wo sie dann nacheinander abgearbeitet werden. Der MessagePool kann entfallen, wenn auf COM Objekte vom selben Thread aus zugegriffen werden soll. Siehe Beispiel 3. Die Möglichkeit eines STA Servers mehrere STA's zu instanziieren (multithreaded) hat zur Folge das jedes COM Objekt in einem STA zwar die Methodenaufrufe seriell erhält, aber falls per Instanz ein neues STA erzeugt wird, kann das COM Laufzeitmodul gleichzeitig in den verschiedenen STA's auf das STA-Objekt zugreifen. Aus diesem Grund muss ein STA-Objekt alle globalen Daten und Variablen schützen oder sicherstellen, das eine gleichzeitige Verwendung der Daten Threadsave erfolgt. Um in einem Programm von einem STA auf ein STA Objekt in einem anderen STA zugreifen zu können, muss der Interfacepointer des STA Objekts zu dem STA transformiert (marshalling) werden, von dem aus auf das STA Objekt zugegriffen wird. Anders ausgedrückt wird der Interfacepointer des STA Objekts von dem STA aus Exportiert wo es instanziiert wurde und von dem STA aus Importiert von dem aus auf das STA Objekt zugegriffen wird. Das importierende STA wird oft auch als Proxy bezeichnet. Ein einfaches Beispiel ist hier zu sehen. Diese Art der Interfacetransformation erfolgt automatisch vom COM Laufzeitmodul, wenn ein STA Client ein STA Objekt in einem EXE STA Server instanziieren will. Technisch gesehen existieren für ein STA Objekt dann zwei Appartments, eines im Client und eines im Server. Der STA Client erhält einen Proxyinterfacepointer von der Serverapplikation. Der Vorteil mehrere STA's inerhalb eines Programms zu verwenden hat aber auch einen Nachteil. Mit jedem neuen STA verringern sich die freien Systemressourcen. Ab einer bestimmten Threadanzahl geht dann nichts mehr. Das System ist ausgelastet. Um diesen Umstand zu vermeiden, kann man mit Hilfe eines Threadpools die Systemressourcen schonen. Wenn eine definierte Anzahl an Threads erreicht ist, werden neue Objekte auf die vorhandenen Threads verteilt. Nun stellt sich die Frage, wozu gibt es das MTA Modell, wenn mittels des STA Modells auch multithreaded Programme entwickelt werden können. Das MTA Modell verwendet im Gegensatz zum STA Modell ein Apartment in dem alle Threads ausgeführt werden. Der Vorteil dieses Apartments ist das Entfallen der Interfacetransformation (marshaling) zwischen verschiedenen Threads, woraus sich eine maximale Performance ergiebt. Das bedeutet, wird in einem MTA ein COM Objekt instanziiert, so können alle sich im MTA befindlichen Threads dieses COM Objekt direkt ohne Interfacetransformation gleichzeitig manipulieren. Ein serieller Zugriff wie beim STA erfolgt nicht. Alle Threads sind gleichberechtigt. Daraus ergiebt sich folgende Konsequenz: Ein MTA Objekt kann nicht beeinflussen von welchem Thread und zu welcher Zeit ein Methodenaufruf auf sich erfolgt. Um ein MTA Objekt Threadsave zu gestalten, muss es globale und lokale Daten und Variablen auf mehrere gleichzeitige Zugriffe auslegen. |
|||||||||||||||||||||
|
Beispiel 1. CoInitializeEx CoInitalizeEx(pvReserved: Pointer; coInit: LongInt): HResult; stdcall; begin Beispiel 2. MessagePool var Msg: TMsg; begin procedure TSTAThread.Execute; var NewInterface: Pointer; Thread 1: procedure Marshal; Thread 2: procedure UnMarshal; |
|||||||||||||||||||||
|
Microsoft © ist eingetragenes Warenzeichen Microsoft Corporation. |