Multithreading : conseils de programmation MFC
Les applications multithread nécessitent un soin plus strict que les applications monothreads pour s’assurer que les opérations se produisent dans l’ordre prévu, et toutes les données accessibles par plusieurs threads ne sont pas endommagées. Cette rubrique explique les techniques permettant d’éviter les problèmes potentiels lors de la programmation d’applications multithread avec la bibliothèque MFC (Microsoft Foundation Class).
Accès aux objets à partir de plusieurs threads
Les objets MFC ne sont pas thread-safe par eux-mêmes. Deux threads distincts ne peuvent pas manipuler le même objet, sauf si vous utilisez les classes de synchronisation MFC et/ou les objets de synchronisation Win32 appropriés, tels que les sections critiques. Pour plus d’informations sur les sections critiques et d’autres objets connexes, consultez Synchronisation dans le Kit de développement logiciel (SDK) Windows.
La bibliothèque de classes utilise des sections critiques en interne pour protéger les structures de données globales, telles que celles utilisées par l’allocation de mémoire de débogage.
Accès aux objets MFC à partir de threads non-MFC
Si vous avez une application multithread qui crée un thread d’une manière autre que l’utilisation d’un objet CWinThread , vous ne pouvez pas accéder à d’autres objets MFC à partir de ce thread. En d’autres termes, si vous souhaitez accéder à n’importe quel objet MFC à partir d’un thread secondaire, vous devez créer ce thread avec l’une des méthodes décrites dans Multithreading : Création de threads d’interface utilisateur ou multithreading : création de threads de travail. Ces méthodes sont les seules qui permettent à la bibliothèque de classes d’initialiser les variables internes nécessaires pour gérer les applications multithread.
Cartes de handle Windows
En règle générale, un thread peut accéder uniquement aux objets MFC qu’il a créés. Cela est dû au fait que les cartes de handle Windows temporaires et permanentes sont conservées dans le stockage local de threads pour aider à maintenir la protection contre l’accès simultané à partir de plusieurs threads. Par exemple, un thread de travail ne peut pas effectuer de calcul, puis appeler la fonction membre d’un UpdateAllViews
document pour avoir les fenêtres qui contiennent des vues sur les nouvelles données modifiées. Cela n’a aucun effet, car la carte des CWnd
objets aux disques HWND est locale au thread principal. Cela signifie qu’un thread peut avoir un mappage d’un handle Windows vers un objet C++, mais un autre thread peut mapper ce même handle à un autre objet C++. Les modifications apportées dans un thread ne sont pas reflétées dans l’autre.
Il existe plusieurs façons de contourner ce problème. La première consiste à passer des handles individuels (tels qu’un HWND) plutôt qu’à des objets C++ au thread de travail. Le thread de travail ajoute ensuite ces objets à sa carte temporaire en appelant la fonction membre appropriée FromHandle
. Vous pouvez également ajouter l’objet à la carte permanente du thread en appelant Attach
, mais cela doit être effectué uniquement si vous êtes garanti que l’objet existe plus longtemps que le thread.
Une autre méthode consiste à créer des messages définis par l’utilisateur correspondant aux différentes tâches que vos threads de travail effectuent et publient ces messages dans la fenêtre principale de l’application à l’aide ::PostMessage
de . Cette méthode de communication est similaire à deux applications différentes, sauf que les deux threads s’exécutent dans le même espace d’adressage.
Pour plus d’informations sur les cartes de gestion, consultez la note technique 3. Pour plus d’informations sur le stockage local de threads, consultez Stockage local thread et Utilisation du stockage local thread dans le Kit de développement logiciel (SDK) Windows.
Communication entre les threads
MFC fournit un certain nombre de classes qui permettent aux threads de synchroniser l’accès aux objets afin de maintenir la sécurité des threads. L’utilisation de ces classes est décrite dans Multithreading : Utilisation des classes de synchronisation et multithreading : Quand utiliser les classes de synchronisation. Pour plus d’informations sur ces objets, consultez Synchronisation dans le Kit de développement logiciel (SDK) Windows.