Jeśli mam wątek w nieskończonej pętli, czy istnieje sposób na zakończenie go po zakończeniu głównego programu (na przykład po naciśnięciu Ctrl+ C)?
85
Jeśli mam wątek w nieskończonej pętli, czy istnieje sposób na zakończenie go po zakończeniu głównego programu (na przykład po naciśnięciu Ctrl+ C)?
Sprawdź to pytanie. Prawidłowa odpowiedź ma świetne wyjaśnienie, jak zakończyć wątki we właściwy sposób: czy istnieje sposób na zabicie wątku w Pythonie?
Aby zatrzymać wątek po sygnale przerwania klawiatury (ctrl + c), możesz przechwycić wyjątek „Przerwanie klawiatury” i wyczyścić przed zakończeniem. Lubię to:
try:
start_thread()
except (KeyboardInterrupt, SystemExit):
cleanup_stop_thread()
sys.exit()
W ten sposób możesz kontrolować, co robić, gdy program zostanie nagle przerwany.
Możesz także użyć wbudowanego modułu sygnałowego, który pozwala ustawić programy obsługi sygnału (w Twoim przypadku sygnał SIGINT): http://docs.python.org/library/signal.html
cleanup_stop_thread()
to funkcja globalna, której mogę używać? czy powinienem to zaimplementować?Jeśli utworzysz wątki robocze wątków demonów, zginą one, gdy wszystkie wątki inne niż demonowe (np. Wątek główny) zostaną zamknięte.
http://docs.python.org/library/threading.html#threading.Thread.daemon
źródło
isDaemon()
to False, ustaw go jako True przezsetDaemon(True)
.isDaemon()
isetDaemon()
są starymidaemon=True
threading.Thread()
Spróbuj włączyć pod-wątek jako demon-wątek.
Na przykład:
Zalecana:
from threading import Thread t = Thread(target=<your-method>) t.daemon = True # This thread dies when main thread (only non-daemon thread) exits. t.start()
W tekście:
t = Thread(target=<your-method>, daemon=True).start()
Stary interfejs API:
t.setDaemon(True) t.start()
Kiedy twój główny wątek się kończy ("tj. Kiedy naciskam Ctrl+ C"), inne wątki również zostaną zabite przez powyższe instrukcje.
źródło
Użyj modułu atexit standardowej biblioteki Pythona, aby zarejestrować funkcje "kończące", które są wywoływane (w głównym wątku) przy każdym rozsądnie "czystym" zakończeniu głównego wątku, w tym nieprzechwyconych wyjątkach, takich jak
KeyboardInterrupt
. Takie funkcje kończące mogą (choć nieuchronnie w głównym wątku!) Wywołać dowolnąstop
funkcję, której potrzebujesz; wraz z możliwością ustawienia wątku jakodaemon
, daje to narzędzia do prawidłowego zaprojektowania potrzebnej funkcjonalności systemu.źródło
atexit.register()
wywołań w modułach Pythona, powodując, że twoja procedura kończenia zostanie wykonana po tejmultiprocessing
. Uruchamiam w tym problemie zajmując się wątkamiQueue
idaemon
: „Błąd EOF” przy wyjściu programu przy użyciu kolejki wieloprocesowej i wątku .atexit
obsługi nie są wywoływane, gdy wątki inne niż demonowe są aktywne i główny wątek zostaje zamknięty. Zobacz Skrypt utknął podczas zamykania wątków przy użyciu atexit .Jeśli stworzysz taki wątek -
myThread = Thread(target = function)
- a potem zróbmyThread.start(); myThread.join()
. Po zainicjowaniu CTRL-C wątek główny nie kończy pracy, ponieważ oczekuje na tomyThread.join()
wywołanie blokujące . Aby to naprawić, po prostu ustaw limit czasu na wywołanie .join (). Limit czasu może być tak długi, jak chcesz. Jeśli chcesz, aby czekał w nieskończoność, po prostu ustaw naprawdę długi limit czasu, na przykład 99999. Dobrą praktyką jest również zrobienie tego,myThread.daemon = True
aby wszystkie wątki zostały zakończone po zakończeniu głównego wątku (nie będącego demonem).źródło
myThread.daemon = True
to wspaniałe rozwiązanie tego problemu..daemon=True
nie jest solidnym rozwiązaniem. Sprawdź ten wątek, aby uzyskać wyjaśnienie: stackoverflow.com/a/20598791/5562492Wątki demona są zabijane niezręcznie, więc żadne instrukcje finalizatora nie są wykonywane. Możliwym rozwiązaniem jest sprawdzenie, czy główny wątek żyje, a nie nieskończona pętla.
Np. Dla Pythona 3:
while threading.main_thread().isAlive(): do.you.subthread.thing() gracefully.close.the.thread()
Zobacz Sprawdź, czy wątek główny nadal żyje z innego wątku .
źródło