Если у меня есть поток в бесконечном цикле, есть ли способ прекратить его, когда основная программа заканчивается (например, когда я нажимаю Ctrl + C)?
Python: как завершить поток при завершении основной программы
Ответ 1
Проверьте этот вопрос. Правильный ответ имеет отличное объяснение того, как правильно завершать темы: Есть ли способ убить поток в Python?
Чтобы остановить поток по сигналу прерывания клавиатуры (ctrl + c), вы можете перехватить исключение "KeyboardInterrupt" и очистить его перед выходом. Как это:
try:
start_thread()
except (KeyboardInterrupt, SystemExit):
cleanup_stop_thread()
sys.exit()
Таким образом, вы можете контролировать, что делать, когда программа внезапно завершается.
Вы также можете использовать встроенный сигнальный модуль, который позволяет вам настроить обработчики сигналов (в вашем конкретном случае сигнал SIGINT): http://docs.python.org/library/signal.html
Ответ 2
Если вы создаете потоки рабочего потока для рабочих потоков, они умрут, когда все ваши потоки не-демона (например, основной поток) выйдут.
http://docs.python.org/library/threading.html#threading.Thread.daemon
Ответ 3
Используйте atexit модуль стандартной библиотеки Python для регистрации функций "завершения", которые вызываются (по основному потоку) на любом разумном "чистое" завершение основного потока, включая неперехваченное исключение, такое как KeyboardInterrupt
. Такие функции завершения могут (хотя и неизбежно в основном потоке!) Вызывать любую требуемую функцию stop
; вместе с возможностью установки потока как daemon
, который дает вам инструменты для правильного проектирования необходимых вам функций системы.
Ответ 4
Если вы создаете Thread так же - myThread = Thread(target = function)
- и затем выполните myThread.start(); myThread.join()
. Когда инициируется CTRL-C, основной поток не выходит из-за ожидания блокировки вызова myThread.join()
. Чтобы исправить это, просто поставьте тайм-аут на вызов .join(). Тайм-аут может быть до тех пор, пока вы этого хотите. Если вы хотите, чтобы он подождал бесконечно, просто введите очень длинный тайм-аут, например 99999. Также хорошо сделать myThread.daemon = True
, чтобы все потоки выходили, когда основной поток (не-демон) завершает работу.
Ответ 5
Попробуйте включить подпоток как daemon-thread.
Например:
from threading import Thread
threaded = Thread(target=<your-method>)
threaded.daemon = True # This thread dies when main thread (only non-daemon thread) exits.
threaded.start()
Или (в строке):
from threading import Thread
threaded = Thread(target=<your-method>, daemon=True).start()
Когда ваш основной поток завершается ("например, когда я нажимаю Ctrl + C"), другие потоки убивают с помощью приведенной выше инструкции.
Ответ 6
Потоки демона уничтожаются изящно, поэтому любые инструкции финализатора не выполняются. Возможное решение - проверить, является ли основной поток живым, а не бесконечным циклом.
Например. для Python 3:
while threading.main_thread().isAlive():
do.you.subthread.thing()
gracefully.close.the.thread()