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)?
Odpowiedzi:
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
isDaemon()
to False, ustaw go jako True przez setDaemon(True)
.
isDaemon()
i setDaemon()
są starymi daemon=True
threading.Thread()
Spróbuj włączyć pod-wątek jako demon-wątek.
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.
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 jako daemon
, daje to narzędzia do prawidłowego zaprojektowania potrzebnej funkcjonalności systemu.
atexit.register()
wywołań w modułach Pythona, powodując, że twoja procedura kończenia zostanie wykonana po tej multiprocessing
. Uruchamiam w tym problemie zajmując się wątkami Queue
i daemon
: „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ób myThread.start(); myThread.join()
. Po zainicjowaniu CTRL-C wątek główny nie kończy pracy, ponieważ oczekuje na to myThread.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).
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/5562492
Wą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 .