Если у меня есть поток в бесконечном цикле, есть ли способ прекратить его, когда основная программа заканчивается (например, когда я нажимаю 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()