Multithreading: Tipy pro programování
Při přístupu k datům vyžadují vícevláknové aplikace vyšší opatrnost než jednovláknové aplikace.Protože existuje více nezávislých cest v realizaci současného používání ve vícevláknových aplikacích, musí algoritmy, data nebo obojí vědět, zda mohou být data použita více než jedním vláknem současně.Toto téma popisuje techniky pro předcházení potenciálním problémům s použitím knihovny Microsoft Foundation Class (knihovna MFC) při programování vícevláknových aplikací.
Přístup k objektům z více vláken
Přístup k objektům knihovny MFC z vláken mimo knihovnu MFC
Mapování zpracování systému Windows
Komunikace mezi vlákny
Přístup k objektům z více vláken
Z důvodů velikosti a výkonu nejsou objekty knihovny MFC bezpečné pro přístup z více vláken na úrovni objektu, ale pouze na úrovni třídy.To znamená, že můžete mít dvě oddělená vlákna, která zpracovávají dva různé objekty CString, ale nemůžete mít dvě vlákna, která manipulují se stejným objektem CString.Pokud musíte mít nezbytně více vláken manipulujících se stejným objektem, chraňte přístup vhodnými synchronizačními mechanismy Win32, jako jsou například kritické sekce.Další informace o kritických sekcích a jiných souvisejících objektech, naleznete v tématu Synchronizace ve Windows SDK.
Knihovna tříd používá interně kritickou sekci k ochraně globálních datových struktur, které jsou například použity při přidělení ladící paměti.
Přístup k objektům knihovny MFC z vláken mimo knihovnu MFC
Pokud máte vícevláknovou aplikaci, která vytváří vlákno jiným způsobem než použitím objektu CWinThread, nemůžete z tohoto vlákna přistupovat k jiným objektům knihovny MFC.Jinými slovy, pokud chcete získat přístup libovolného objektu knihovny MFC z jiného vlákna, je nutné vytvořit toto vlákno jednou z metod popsaných v Multithreading: vytváření vláken uživatelského rozhraní nebo Multithreading: vytváření pracovních vláken.Tyto metody jsou jediné, kterým povoluje knihovna tříd inicializovat vnitřní proměnné, které jsou nutné ke zpracování vícevláknových aplikací.
Mapování zpracování systému Windows
Z obecného pravidla platí, že může být přístupné vlákno pouze těm objektům knihovny MFC, které toto vlákno vytvořily.Důvodem je to, že dočasná nebo trvalá mapování zpracování systému Windows jsou uloženy v místním úložném prostoru vlákna, pro zachování ochrany před současným přístupem z více vláken.Například pracovní vlákno nemůže provádět výpočet a poté zavolat členskou funkci UpdateAllViews dokumentu, pro získání okna, obsahujícího zobrazení nových upravených dat.To nemá žádný účinek, protože mapa z objektů CWnd na HWND je umístěna na primární vlákno. To znamená, že jedno vlákno může obsahovat mapování ze zpracování systému Windows na objekt jazyka C++, ale jiné vlákno může mapovat stejné zpracování na jiný objekt jazyka C++.Změny provedené v jednom vlákně se nemusí projevit v jiném vlákně.
Tento problém lze vyřešit několika způsoby.Prvním je předat do pracovního vlákna jednotlivé popisovače (například HWND) místo objektů jazyka C++.Pracovní vlákno poté přidá tyto objekty do jeho dočasné mapy voláním příslušné členské funkce FromHandle. Můžete také přidat objekt do dočasné mapy vlákna, zavoláním Attach, ale to by mělo být provedeno pouze v případě, že je zaručeno, že objekt bude existovat déle než vlákno.
Jiný způsob je vytvořit nové uživatelsky definované zprávy odpovídající různým úlohám. Vaše pracovní vlákna budou provádět a odesílat tyto zprávy hlavnímu oknu aplikace pomocí příkazu :: PostMessage.Tento způsob komunikace je podobný konverzaci mezi dvěma různými aplikacemi s tím rozdílem, že jsou obě vlákna spuštěna ve stejném adresním prostoru.
Další informace o mapování zpracování naleznete v tématu Technické poznámky 3.Další informace o vlákně místního úložiště naleznete v tématech Místní úložný prostor vlákna a Použití místního úložného prostoru vlákna v Windows SDK.
Komunikace mezi vlákny
Knihovna MFC poskytuje několik tříd, které povolují vláknům synchronizovat přístup k objektům pro zachování vláknové bezpečnosti.Použití těchto tříd je popsán v Multithreading: jak použít třídy synchronizace a Multithreading: kdy použít synchronizační třídy.Další informace o těchto objektech naleznete v tématu Synchronizace ve Windows SDK.