Multithreading: MFC-Programmiertipps
Multithread-Anwendungen erfordern eine striktere Pflege als Singlethread-Anwendungen, um sicherzustellen, dass Vorgänge in der beabsichtigten Reihenfolge auftreten, und alle Daten, auf die von mehreren Threads zugegriffen wird, sind nicht beschädigt. In diesem Thema werden die Methoden beschrieben, mit denen potenzielle Probleme bei der Programmierung von Multithreadanwendungen mit Microsoft Foundation Class Library (MFC) vermieden werden können.
Zugreifen auf Objekte aus mehreren Threads
MFC-Objekte sind nicht selbst threadsicher. Zwei separate Threads können dasselbe Objekt nicht bearbeiten, es sei denn, Sie verwenden die MFC-Synchronisierungsklassen und/oder die entsprechenden Win32-Synchronisierungsobjekte, z. B. kritische Abschnitte. Weitere Informationen zu kritischen Abschnitten und anderen verwandten Objekten finden Sie unter "Synchronisierung " im Windows SDK.
In der Klassenbibliothek werden kritische Abschnitte intern zum Schutz globaler Datenstrukturen verwendet. Diese Datenstrukturen werden z. B. von der Debugspeicherbelegung verwendet.
Zugreifen auf MFC-Objekte aus Nicht-MFC-Threads
Wenn Sie über eine Multithreadanwendung verfügen, die einen Thread auf eine andere Weise als die Verwendung eines CWinThread-Objekts erstellt, können Sie nicht auf andere MFC-Objekte aus diesem Thread zugreifen. Anders ausgedrückt: Wenn Sie von einem sekundären Thread aus auf ein MFC-Objekt zugreifen möchten, müssen Sie diesen Thread mit einer der in Multithreading beschriebenen Methoden erstellen: Erstellen von Benutzeroberflächenthreads oder Multithreading: Erstellen von Arbeitsthreads. Nur mithilfe dieser Methoden kann die Klassenbibliothek die internen Variablen initialisieren, die zur Behandlung von Multithreadanwendungen erforderlich sind.
Windows Handle Maps
Grundsätzlich kann ein Thread nur auf die von ihm erstellten MFC-Objekte zugreifen. Der Grund hierfür ist, dass temporäre und permanente Windows-Handlezuordnungen im lokalen Threadspeicher verwaltet werden. Auf diese Weise soll der gleichzeitige Zugriff von mehreren Threads aus verhindert werden. Ein Arbeitsthread kann z. B. keine Berechnung durchführen und anschließend die UpdateAllViews
-Memberfunktion eines Dokuments aufrufen, um die Fenster zu ändern, die Ansichten der neuen Daten enthalten. Dies hat überhaupt keine Auswirkung, da die Zuordnung von CWnd
Objekten zu HWNDs lokal zum primären Thread ist. Dies bedeutet, dass ein bestimmter Thread möglicherweise eine Zuordnung eines Windows-Handles zu einem C++-Objekt aufweist, ein anderer Thread dasselbe Handle jedoch unter Umständen einem anderen C++-Objekt zuordnet. Änderungen, die in einem Thread vorgenommen wurden, werden in einem anderen Thread nicht widergespiegelt.
Es gibt verschiedene Methoden zur Umgehung dieses Problems: Die erste besteht darin, einzelne Handles (z. B. ein HWND) anstelle von C++-Objekten an den Arbeitsthread zu übergeben. Der Arbeitsthread fügt anschließend diese Objekte seiner temporären Zuordnung hinzu, indem er die entsprechende FromHandle
-Memberfunktion aufruft. Sie können das Objekt auch zur permanenten Zuordnung des Threads hinzufügen, indem Sie dies aufrufen Attach
. Dies sollte jedoch nur erfolgen, wenn Sie garantiert sind, dass das Objekt länger als der Thread vorhanden ist.
Eine weitere Methode besteht darin, neue benutzerdefinierte Nachrichten zu erstellen, die den verschiedenen Aufgaben entsprechen, die Ihre Arbeitsthreads ausführen und diese Nachrichten mithilfe ::PostMessage
des Hauptfensters der Anwendung veröffentlichen. Diese Kommunikationsmethode ist mit dem Informationsaustausch zwischen zwei Anwendungen vergleichbar; der Unterschied besteht darin, dass beide Threads im selben Adressbereich ausgeführt werden.
Weitere Informationen zu Handlemaps finden Sie in technischem Hinweis 3. Weitere Informationen zum lokalen Threadspeicher finden Sie unter Thread Local Storage und Using Thread Local Storage im Windows SDK.
Kommunikation zwischen Threads
MFC enthält eine Anzahl von Klassen, die es Threads ermöglichen, den Zugriff auf Objekte zu synchronisieren und so die Threadsicherheit aufrechtzuerhalten. Die Verwendung dieser Klassen wird in Multithreading beschrieben: Verwenden der Synchronisierungsklassen und Multithreading: Verwendung der Synchronisierungsklassen. Weitere Informationen zu diesen Objekten finden Sie unter "Synchronisierung " im Windows SDK.