2010-04-01 19 views

Odpowiedz

35

Sprawdź to pytanie. Prawidłowa odpowiedź ma wielki wyjaśnienie, w jaki sposób zakończyć wątki właściwej drodze: Is there any way to kill a Thread in Python?

Aby ogranicznik wątek na klawiaturze sygnał przerwania (Ctrl + C) można złapać wyjątek „KeyboardInterrupt” i porządki przed wyjściem. Tak:

try: 
    start_thread() 
except (KeyboardInterrupt, SystemExit): 
    cleanup_stop_thread() 
    sys.exit() 

W ten sposób można kontrolować, co zrobić, gdy program zostanie nagle przerwane.

Można również użyć wbudowanego modułu sygnałowego, który pozwala konfiguracji obsługi sygnałów (w konkretnym przypadku sygnału SIGINT): http://docs.python.org/library/signal.html

+0

Bardzo dziękuję za odpowiedź. Być może nie odpowiedziałem poprawnie na pytanie. W przykładzie podanym w tym pytaniu nadal konieczne było wykonanie funkcji stop() dla wątku. Kiedy nieprawidłowo kończę program przez ctrl + C, to nie może się zdarzyć. Tak, moje pytanie brzmi trochę jak: "jak wywołać funkcję mythread.stop(), jeśli główny wątek został przerwany" – facha

+0

Edytowałem moje pytanie :) – rogeriopvl

+2

Jak jeszcze nikt nie zauważył średnika w twoim przykładzie kodu? Uwielbiam to! –

65

Jeśli dokonać pracownik podaje wątki demon, umrą gdy wszyscy twoi wątki inne niż demony (np. główny wątek) zostały zakończone.

http://docs.python.org/library/threading.html#threading.Thread.daemon

+2

Dzięki za prostą i precyzyjną odpowiedź, domyślne wątkowanie. Status demona 'isDaemon()' jest fałszywy, ustaw go jako True przez 'setDaemon (True)'. – Tony

+1

To odpowiada na pytanie i po prostu działa. Operacja nie zapytała, jak ogólnie wyłączyć wątki. –

9

Użyj moduł biblioteki standardowej Pythona atexit zarejestrować funkcji „zakończenie”, które się nazywa (w głównym wątku) na wszelkie możliwe „czystej” zakończenia głównego wątku, w tym nieprzechwycony wyjątkiem takich jak KeyboardInterrupt. Takie funkcje zakończenia mogą (choć nieuchronnie w głównym wątku!) Wywoływać dowolną wymaganą funkcję stop; wraz z możliwością ustawienia wątku jako daemon, który zapewnia narzędzia do prawidłowego projektowania funkcjonalności systemu, której potrzebujesz.

+0

Należy zauważyć, że to podejście zadziałało bez potrzeby demonizowania wątków w wersjach Pythona wcześniejszych niż 2.6.5, zobacz odpowiedź na http://stackoverflow.com/questions/3713360/python-2-6-x-theading-signals-atexit-fail- w niektórych wersjach. To niefortunne IMHO, ponieważ wątki demona podczas zamykania są trochę bałaganem przed pythonem 3.4 (http://bugs.python.org/issue19466). Jeśli zatrzymasz _i_ dołączenie do wątków demona w twoich atexitowych programach obsługi, wszystko powinno być w porządku, przy (prawdopodobnie nieznacznym) koszcie uszeregowania twojej oderwanej nici. – NeilenMarais

4

Jeśli odradzasz wątek taki jak ten - myThread = Thread(target = function) - a następnie wykonaj myThread.start(); myThread.join(). Po uruchomieniu CTRL-C wątek główny nie wychodzi, ponieważ oczekuje na to wywołanie blokujące myThread.join(). Aby to naprawić, po prostu ustaw limit czasu dla wywołania .join(). Limit czasu może być tak długi, jak chcesz. Jeśli chcesz czekać w nieskończoność, po prostu ustaw się naprawdę długo, np. 99999. Dobrą praktyką jest też wykonywanie myThread.daemon = True, tak aby wszystkie wątki kończyły się po wyjściu głównego wątku (nie-demona).

+0

'myThread.daemon = True' jest wspaniałym rozwiązaniem tego problemu. – Brannon

+0

@Brannon '.daemon = True' nie jest rozwiązaniem trwałym. Sprawdź ten wątek, aby uzyskać wyjaśnienie: https://stackoverflow.com/a/20598791/5562492 –

Powiązane problemy