Wielowątkowość: przerywanie wątków
Dwie normalne sytuacje powodują koniec ciągu: funkcja kontrolowania istnieje lub wątek nie może dobiec do końca.Jeśli edytor tekstu używa wątku do drukowania w tle, funkcja kontrolna zakończy się normalnie, jeśli drukowanie zostanie ukończone pomyślnie.Jeśli użytkownik chce, aby anulować drukowanie, natomiast wątek drukowanie w tle musi być zakończony przedwcześnie.Temat tłumaczy jak implementować każdą sytuację oraz jak pozyskać kod wyjścia z ciągu po jego zakończeniu.
Zakończenie normalne wątku
Przedwczesne zakończenie wątku
Pobieranie kodu wyjścia wątku
Zakończenie normalne wątku
W przypadku wątku roboczego zakończenie zwykłych wątków jest proste. Zamknij funkcję kontrolującą i zwróć wartość, która oznacza powód zakończenia.Można użyć albo funkcji AfxEndThread albo instrukcji return.typowo, 0 oznacza pomyślne ukończenie. ale zależy to od Ciebie.
W przypadku wątku interfejsu użytkownika ten proces jest równie prosty: z wątku interfejsu użytkownika wywołaj PostQuitMessage w Windows SDK.Jedynym parametrem, który jest przyjmowany przez PostQuitMessage jest kod wyjścia wątku.Jak w przypadku wątków roboczych, 0 zazwyczaj oznacza pomyślne zakończenie.
Przedwczesne zakończenie wątku
Przedwczesne zakończenie wątku jest prawie tak samo proste: wywołanie AfxEndThread z wewnątrz wątku.Przekaż żądany kod zakończenia jako jedyny parametr.To zatrzymuje wykonanie ciągu, dealokuje stos ciągu, odłącza wszystkie połączone do ciągu DLL oraz usuwa obiekt ciągu z pamięci.
AfxEndThread musi być wywołana z wewnątrz wątku, aby zostać zakończona.Jeśli chcesz zakończyć wątek z innego wątku, należy zdefiniować metodę komunikacji pomiędzy dwoma wątkami.
Pobieranie kodu wyjścia wątku
Aby uzyskać kod wyjścia dla każdego pracownika lub wątku interfejsu użytkownika, wywołaj funkcję GetExitCodeThread.Aby uzyskać więcej informacji o tej funkcji, zobacz Windows SDK.Ta funkcja pobiera uchwyt do wątku (przechowywany w m_hThread elemencie członkowskim danych CWinThread obiektów) oraz adres DWORD.
Jeśli wątek jest nadal aktywny, GetExitCodeThread umieszcza STILL_ACTIVE w podanym adresie DWORD; w przeciwnym razie kod wyjścia jest umieszczany w tym adresie.
Pobieranie kodu wyjścia obiektów CWinThread wymaga dodatkowego kroku.Domyślnie gdy CWinThread wątek kończy działanie, obiekt wątku jest usuwany.Oznacza to, że nie posiadasz dostępu do elementu członkowskiego danych m_hThread, ponieważ obiekt CWinThread już nie istnieje.Aby uniknąć tej sytuacji, wykonaj jedną z następujących czynności:
Ustaw element członkowski danych m_bAutoDelete na FAŁSZ.Pozwala to obiektowi CWinThread przetrwać po tym jak został usunięty wątek.Możesz uzyskać dostęp do elementu członkowskiego danych m_hThread po zakończeniu wątku.Jeśli korzystasz z tej techniki, ponosisz jednak odpowiedzialność za zniszczenie obiektu CWinThread, ponieważ szablon nie usunie jej automatycznie dla Ciebie.To metoda preferowana.
Przechowaj uchwyt wątku oddzielnie.Po utworzeniu wątku, należy skopiować jego m_hThread element członkowski danych (za pomocą :: DuplicateHandle) do innej zmiennej i uzyskać do niego dostęp za pośrednictwem tej zmiennej.W ten sposób obiekt jest automatycznie usuwany kiedy następuje koniec i możesz wciąż dowiedzieć się dlaczego wątek się zakończył.Należy zachować ostrożność, żeby wątek nie skończył się, zanim będzie można zduplikować dojście.najbezpieczniejszy sposób, aby przekazać CREATE_SUSPENDED do AfxBeginThread, przechowaj uchwyt, a następnie wznów wątek wywołując ResumeThread.
Każda z tych metod pozwala określić dlaczego CWinThread obiekt został zakończony.