2009-11-06 24 views
5

Chcę zaimplementować przerywane zadania na podstawie wątków tła. Jaki jest najczystszy sposób wdrożenia metody TTask.Stop? Jak mogę przerwać wątek tła?Przerwać wątek?

Kod wykonywany w kontekście wątku jest przekazywany do zadania przy użyciu metody anonimowej i może zawierać wywołania blokujące, więc nie mogę polegać na tym, że flaga Terminated jest regularnie sprawdzana z poziomu kodu.

Dzięki za wszelkie dane wejściowe.

Korzystanie D2010 w przypadku jest to ważne (niektóre rzeczy w TThread wydają się zmieniły)

Odpowiedz

7

nie ma sposobu, aby bezpiecznie przerwać nić. Dotyczy to programów Windows napisanych w Delphi, czy też nie, i czy korzystasz z Delphi 2010 lub wcześniejszego. Jest to ograniczenie OS, jeśli chcesz tak je nazwać, ale w rzeczywistości jest to ograniczenie wątków, przerywanie wątku bez upewnienia się, że nie ma blokad lub czegoś w tym rodzaju, może siać spustoszenie w twoim programie.

Co można zrobić, to wywołać funkcję API TerminateThread(), która jest Zła. Przeczytaj listę problemów i ostrzeżeń w tym łączu i sprawdź, czy nadal chcesz do niej zadzwonić. Nie ma innego sposobu, który działa bez współpracy z kodem zadania.

7

Izoluj zadanie w oddzielnym procesie. W zależności od tego, jak się komunikujesz z zadaniem w tle, jest to prawdopodobnie najlepszy sposób na zagwarantowanie, że możesz go usunąć w sposób czysty.

Na przykład, prawdopodobnie nie jest dobrym pomysłem wykorzystanie pamięci współdzielonej do komunikacji; używaj plików lub potoków lub podobnego mechanizmu, który nie łamie się lub nie blokuje, gdy drugi koniec zostanie zabity. Jeśli używasz nazwanych muteksów do synchronizacji między procesami, pamiętaj, że dla tych prymitywów synchronizacji istnieje określony stan błędu: WAIT_ABANDONED jest zwracana przez WaitForSingleObject i znajomych, jeśli wątek (lub, niejawnie główny wątek procesu), w którym był pierwotny prymityw zakończone bez jego całkowitego zwolnienia. Zasadniczo oznacza to, że musisz użyć etapowego podejścia transakcyjnego do transferu danych, abyś mógł zignorować potencjalnie niespójny stan, który był modyfikowany w momencie zakończenia.

+0

To jest dobra (+1) odpowiedź; cf. Python threading, w którym wiele jest zrobione z Global Interpreter Lock, który jest odpowiedzialny zarówno za bezpieczeństwo wątków (dobre), jak i na wszelkie praktyczne potrzeby ogranicza wielowątkowy kod do pojedynczego rdzenia (zły). Najlepszym rozwiązaniem tego problemu jest nie używanie wątków, lecz raczej procesów za pomocą pakietu wieloprocesowego, a także to, co zyskuje ta natychmiastowa zdolność skalowania na wielu komputerach, co w końcu staje się konieczne do dużego skalowania. Zamiast martwić się o bezpieczeństwo wątków, lepiej byłoby mieć łatwe (łatwiejsze) zarządzanie wieloprocesowe w Delphi. –

+0

Semafory nie mają stanu "porzucony", ponieważ nie mają wbudowanego pojęcia własności. (Jeśli chodzi o system operacyjny, wątek nie może "utrzymać" semafora.) Tylko muteks może zostać porzucony w sposób wykrywalny. –

+0

To może być dobry sposób implementacji zadań przerywalnych z blokowaniem kodu, jednak nie widzę, jak należy zaimplementować funkcjonalność w pytaniu (przerywalne zadanie dla metod anonimowych) w Delphi. Musiałby istnieć kompilator środowiska wykonawczego, aby utworzyć plik wykonywalny (który będzie tworzony jako inny proces) z anonimowej metody, nie? – mghie