Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Dans un modèle d’appartement multithread, tous les threads du processus qui ont été initialisés en tant que threads libres résident dans un seul appartement. Par conséquent, il n’est pas nécessaire de marshaler entre les threads. Les threads n’ont pas besoin de récupérer et de distribuer des messages, car COM n’utilise pas de messages de fenêtre dans ce modèle.
Les appels aux méthodes d’objets de l’appartement multithread peuvent être exécutés sur n’importe quel thread de l’appartement. Il n’y a pas de sérialisation des appels ; de nombreux appels peuvent se produire simultanément à la même méthode ou au même objet. Les objets créés dans l’appartement multithread doivent être en mesure de gérer les appels sur leurs méthodes à partir d’autres threads à tout moment.
Étant donné que les appels aux objets ne sont pas sérialisés de quelque manière que ce soit, la concurrence d’objets multithread offre les performances les plus élevées et tire le meilleur parti du matériel multiprocesseur pour les appels entre threads, interprocesseurs et inter-ordinateurs. Cela signifie toutefois que le code des objets doit fournir la synchronisation dans leurs implémentations d’interface, généralement à l’aide de primitives de synchronisation telles que des objets d’événement, des sections critiques, des mutex ou des sémaphores, qui sont décrits plus loin dans cette section. En outre, étant donné que l’objet ne contrôle pas la durée de vie des threads qui y accèdent, aucun état spécifique au thread ne peut être stocké dans l’objet (dans le stockage local de thread).
Voici quelques considérations importantes relatives à la synchronisation pour les appartements multithreads :
- COM fournit la synchronisation des appels pour les appartements à thread unique uniquement.
- Les appartements multithreads ne reçoivent pas d’appels lors de l’exécution d’appels (sur le même thread).
- Les appartements multithread ne peuvent pas effectuer d’appels synchronisés en entrée.
- Les appels asynchrones sont convertis en appels synchrones dans des appartements multithreads.
- Le filtre de message n’est appelé pour aucun thread d’un appartement multithread.
Pour initialiser un thread en tant que thread libre, appelez CoInitializeEx, en spécifiant COINIT_MULTITHREADED. Pour plus d’informations sur le thread de serveur in-process, consultez In-Process Problèmes de thread de serveur.
Plusieurs clients peuvent appeler simultanément, à partir de différents threads, un objet qui prend en charge le thread libre. Dans les serveurs hors processus sans threads, COM, via le sous-système RPC, crée un pool de threads dans le processus serveur et un appel client (ou plusieurs appels clients) peuvent être remis par l’un de ces threads à tout moment. Un serveur hors processus doit également implémenter la synchronisation dans sa fabrique de classes. Les objets in-process gratuits peuvent recevoir des appels directs de plusieurs threads du client.
Le client peut effectuer un travail COM dans plusieurs threads. Tous les threads appartiennent au même appartement multithread. Les pointeurs d’interface sont passés directement du thread au thread dans un appartement multithread. Les pointeurs d’interface ne sont donc pas marshalés entre ses threads. Les filtres de messages (implémentations de IMessageFilter) ne sont pas utilisés dans les appartements multithreads. Le thread client s’interrompt lorsqu’il effectue un appel COM vers des objets hors appartement et reprend lorsque l’appel est retourné. Les appels entre les processus sont toujours gérés par RPC.
Les threads initialisés avec le modèle libre-thread doivent implémenter leur propre synchronisation. Comme mentionné précédemment dans cette section, Windows active cette implémentation via les primitives de synchronisation suivantes :
- Les objets d’événement fournissent un moyen de signaler un ou plusieurs threads qu’un événement a eu lieu. Tout thread au sein d’un processus peut créer un objet d’événement. Un handle de l’événement est retourné par la fonction de création d’événements, CreateEvent. Une fois qu’un objet d’événement a été créé, les threads avec un handle à l’objet peuvent attendre avant de poursuivre l’exécution.
- Les sections critiques sont utilisées pour une section de code qui nécessite un accès exclusif à un ensemble de données partagées avant qu’elles ne puissent être exécutées et utilisées que par les threads au sein d’un seul processus. Une section critique est semblable à un tourniquet par lequel un seul thread à la fois peut passer, fonctionnant comme suit :
- Pour vous assurer qu’aucun thread à la fois n’accède aux données partagées, le thread principal d’un processus alloue une structure de données globale CRITICAL_SECTION et initialise ses membres. Un thread entrant dans une section critique appelle la fonction EnterCriticalSection et modifie les membres de la structure de données.
- Un thread qui tente d’entrer une section critique appelle EnterCriticalSection qui vérifie si la structure de données CRITICAL_SECTION a été modifiée. Dans ce cas, un autre thread se trouve actuellement dans la section critique et le thread suivant est mis en veille. Un thread quittant une section critique appelle LeaveCriticalSection, qui réinitialise la structure de données. Lorsqu’un thread quitte une section critique, le système réveille l’un des threads en veille, qui entre ensuite dans la section critique.
- Les mutex effectuent la même fonction qu’une section critique, sauf que le mutex est accessible aux threads s’exécutant dans différents processus. Posséder un objet mutex est comme avoir le sol dans un débat. Un processus crée un objet mutex en appelant la fonction CreateMutex, qui retourne un handle. Le premier thread demandant un objet mutex obtient la propriété de celui-ci. Une fois le thread terminé avec le mutex, la propriété passe à d’autres threads sur une base de première venue et de premier service.
- Les sémaphores sont utilisés pour conserver un nombre de références sur certaines ressources disponibles. Un thread crée un sémaphore pour une ressource en appelant la fonction CreateSemaphore et en passant un pointeur vers la ressource, un nombre de ressources initial et le nombre maximal de ressources. Cette fonction retourne un handle. Un thread demandant une ressource transmet son handle sémaphore dans un appel à la fonction WaitForSingleObject. L’objet sémaphore interroge la ressource pour déterminer s’il est disponible. Dans ce cas, le sémaphore décrémente le nombre de ressources et réveille le thread en attente. Si le nombre est égal à zéro, le thread reste endormi jusqu’à ce qu’un autre thread libère une ressource, ce qui entraîne l’incrémentation du sémaphore à un.
Rubriques connexes
-
Problèmes de thread de serveur In-Process
-
processus , threads et appartements
-
Single-Threaded et de communication multithread