Sdílet prostřednictvím


Multithreading: Ukončování vláken v prostředí MFC

Dvě normální situace způsobí ukončení vlákna: řídicí funkce se ukončí nebo vlákno není povoleno spouštět do dokončení. Pokud textový procesor použil vlákno pro tisk na pozadí, řídicí funkce by se normálně ukončila, pokud se tisk úspěšně dokončil. Pokud ale uživatel chce tisk zrušit, musí být vlákno pro tisk na pozadí ukončeno předčasně. Toto téma vysvětluje, jak implementovat každou situaci a jak získat ukončovací kód vlákna po ukončení.

Normální ukončení vlákna

Pro pracovní vlákno je normální ukončení vlákna jednoduché: Ukončete řídicí funkci a vraťte hodnotu, která označuje důvod ukončení. Můžete použít funkci AfxEndThread nebo return příkaz. Obvykle 0 označuje úspěšné dokončení, ale to je na vás.

Pro vlákno uživatelského rozhraní je proces stejně jednoduchý: z vlákna uživatelského rozhraní volejte PostQuitMessage v sadě Windows SDK. Jediný parametr, který PostQuitMessage přebírá, je ukončovací kód vlákna. Pokud jde o pracovní vlákna, 0 obvykle označuje úspěšné dokončení.

Předčasné ukončení vlákna

Ukončení vlákna je téměř stejně jednoduché: Volání AfxEndThread z vlákna. Jako jediný parametr předejte požadovaný ukončovací kód. Tím se zastaví spuštění vlákna, uvolní se zásobník vlákna, odpojte všechny knihovny DLL připojené k vláknu a odstraníte objekt vlákna z paměti.

AfxEndThread musí být volána z vlákna, která má být ukončena. Pokud chcete ukončit vlákno z jiného vlákna, musíte nastavit komunikační metodu mezi dvěma vlákny.

Načtení ukončovacího kódu vlákna

Chcete-li získat ukončovací kód pracovního procesu nebo vlákna uživatelského rozhraní, zavolejte funkci GetExitCodeThread . Informace o této funkci naleznete v sadě Windows SDK. Tato funkce přebírá popisovač do vlákna (uloženého v datovém m_hThread členu CWinThread objektů) a adresu DWORD.

Pokud je vlákno stále aktivní, GetExitCodeThread umístí STILL_ACTIVE na zadanou adresu DWORD. Jinak se do této adresy umístí ukončovací kód.

Načtení ukončovacího kódu objektů CWinThread provede další krok. Ve výchozím nastavení, když vlákno CWinThread ukončí, objekt vlákna je odstraněn. To znamená, že nemůžete získat přístup k datovému členu m_hThread CWinThread , protože objekt již neexistuje. Pokud se chcete této situaci vyhnout, udělejte jednu z těchto věcí:

  • m_bAutoDelete Nastavte datový člen na FALSE. To umožňuje CWinThread objektu přežít po ukončení vlákna. Po ukončení vlákna pak můžete získat přístup k datovému m_hThread členu. Pokud však použijete tuto techniku, zodpovídáte za zničení objektu CWinThread , protože architektura ho automaticky neodstraní za vás. Toto je upřednostňovaná metoda.

  • Uložte rukojeť vlákna samostatně. Po vytvoření vlákna zkopírujte jeho m_hThread datový člen (pomocí ::DuplicateHandle) do jiné proměnné a přejděte k němu prostřednictvím této proměnné. Tímto způsobem se objekt automaticky odstraní, když dojde k ukončení, a stále můžete zjistit, proč vlákno skončilo. Před duplikátem popisovače buďte opatrní, že se vlákno neukončí. Nejbezpečnější způsob, jak to udělat, je předat CREATE_SUSPENDED AfxBeginThread, uložit popisovač a potom pokračovat ve vlákně voláním ResumeThread.

Obě metody umožňují určit, proč CWinThread se objekt ukončil.

Viz také

Multithreading s použitím jazyka C++ a prostředí MFC
_endthread, _endthreadex
_beginthread, _beginthreadex
ExitThread