Multithreading: Tipy pro programování mfc
Vícevláknové aplikace vyžadují přísnější péči než jednovláknové aplikace, aby se zajistilo, že k operacím dochází v zamýšleném pořadí a všechna data, ke kterým přistupuje více vláken, nejsou poškozena. Toto téma vysvětluje techniky pro zabránění potenciálním problémům při programování vícevláknových aplikací pomocí knihovny MFC (Microsoft Foundation Class).
Přístup k objektům z více vláken
Objekty MFC nejsou samy o sobě bezpečné pro přístup z více vláken. Dvě samostatná vlákna nemohou manipulovat se stejným objektem, pokud nepoužíváte synchronizační třídy MFC nebo příslušné synchronizační objekty Win32, například kritické části. Další informace o důležitých oddílech a dalších souvisejících objektech naleznete v tématu Synchronizace v sadě Windows SDK.
Knihovna tříd interně používá kritické části k ochraně globálních datových struktur, jako jsou například ty, které používá přidělení paměti ladění.
Přístup k objektům MFC z vláken jiných než MFC
Pokud máte vícevláknovou aplikaci, která vytváří vlákno jiným způsobem než pomocí objektu CWinThread , nemůžete z tohoto vlákna získat přístup k jiným objektům MFC. Jinými slovy, pokud chcete získat přístup k libovolnému objektu MFC ze sekundárního vlákna, musíte toto vlákno vytvořit pomocí jedné z metod popsaných v tématu Multithreading: Vytváření vláken uživatelského rozhraní nebo vícevláknů: Vytváření pracovních vláken. Tyto metody jsou jedinými metodami, které knihovně tříd umožňují inicializovat interní proměnné potřebné ke zpracování vícevláknových aplikací.
Mapy úchytů systému Windows
Obecně platí, že vlákno má přístup pouze k objektům MFC, které vytvořil. Důvodem je to, že dočasné a trvalé mapy popisovačů Windows se uchovávají v místním úložišti vláken, aby se zachovala ochrana před souběžným přístupem z více vláken. Pracovní vlákno například nemůže provést výpočet a potom volat členskou UpdateAllViews
funkci dokumentu, aby byla změněna okna obsahující zobrazení nových dat. To nemá vůbec žádný vliv, protože mapa z CWnd
objektů na HWND je místní pro primární vlákno. To znamená, že jedno vlákno může mít mapování z úchytu Systému Windows na objekt C++, ale jiné vlákno může mapovat stejný popisovač na jiný objekt C++. Změny provedené v jednom vlákně by se neprojevily v druhém.
Existuje několik způsobů, jak tento problém obejít. Prvním je předání jednotlivých popisovačů (například HWND) místo objektů C++ do pracovního vlákna. Pracovní vlákno pak tyto objekty přidá do dočasné mapy voláním příslušné FromHandle
členské funkce. Objekt můžete také přidat do trvalé mapy vlákna voláním Attach
, ale to by mělo být provedeno pouze v případě, že jste zaručeni, že objekt bude existovat déle než vlákno.
Další metodou je vytvoření nových uživatelem definovaných zpráv odpovídajících různým úlohám, které budou pracovní vlákna provádět, a publikovat tyto zprávy do hlavního okna aplikace pomocí ::PostMessage
. Tato metoda komunikace je podobná dvěma různým aplikacím, které konversují s tím rozdílem, že obě vlákna se spouštějí ve stejném adresního prostoru.
Další informace o popisovači map naleznete v technické poznámce 3. Další informace o místním úložišti vlákna naleznete v tématu Místní úložiště vláken a Použití místního úložiště vláken v sadě Windows SDK.
Komunikace mezi vlákny
MFC poskytuje řadu tříd, které umožňují vlákenm synchronizovat přístup k objektům za účelem zachování bezpečnosti vlákna. Použití těchto tříd je popsáno v Multithreading: Jak používat synchronizační třídy a multithreading: Kdy použít synchronizační třídy. Další informace o těchto objektech naleznete v tématu Synchronizace v sadě Windows SDK.