Если у меня есть поток в бесконечном цикле, есть ли способ завершить его, когда основная программа завершится (например, когда я нажму Ctrl+ C)?
Ответы:
Отметьте этот вопрос. Правильный ответ содержит отличное объяснение того, как правильно завершить потоки: есть ли способ убить поток в Python?
Чтобы остановить поток по сигналу прерывания клавиатуры (ctrl + c), вы можете перехватить исключение «KeyboardInterrupt» и выполнить очистку перед выходом. Как это:
try:
start_thread()
except (KeyboardInterrupt, SystemExit):
cleanup_stop_thread()
sys.exit()
Таким образом, вы можете контролировать, что делать, когда программа внезапно завершается.
Вы также можете использовать встроенный модуль сигналов, который позволяет настраивать обработчики сигналов (в вашем конкретном случае сигнал SIGINT): http://docs.python.org/library/signal.html
cleanup_stop_thread()
глобальная функция , которую я могу использовать? или мне нужно это реализовать?
Если вы сделаете свои рабочие потоки демоническими потоками, они умрут, когда все ваши недемонические потоки (например, основной поток) завершатся.
http://docs.python.org/library/threading.html#threading.Thread.daemon
isDaemon()
имеет статус False, установите True с помощью setDaemon(True)
.
isDaemon()
и setDaemon()
являются старыми геттерами / сеттерами (согласно приведенному выше документу), просто используйте daemon=True
inthreading.Thread()
Попробуйте включить подпоток как поток-демон.
Рекомендуемые:
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()
В линию:
t = Thread(target=<your-method>, daemon=True).start()
Старый API:
t.setDaemon(True)
t.start()
Когда ваш основной поток завершается («т.е. когда я нажимаю Ctrl+ C»), другие потоки также будут убиты в соответствии с приведенными выше инструкциями.
Используйте модуль atexit стандартной библиотеки Python для регистрации функций «завершения», которые вызываются (в основном потоке) при любом разумно «чистом» завершении основного потока, включая неперехваченное исключение, такое как KeyboardInterrupt
. Такие функции завершения могут (хотя неизбежно в основном потоке!) Вызывать любую stop
функцию, которая вам нужна; вместе с возможностью настройки потока as daemon
, это дает вам инструменты для правильного проектирования необходимых вам системных функций.
atexit.register()
вызовов в модулях Python могут происходить странные вещи , в результате чего ваша процедура завершения будет выполняться после процедуры завершения multiprocessing
. Я бег в этой проблеме , ЗАНИМАЮЩИЙСЯ Queue
и daemon
нитях: «ошибка EOF» при выходе из программы с использованием многопроцессорной обработки очереди и темы .
atexit
обработчики не вызываются, когда не- демонические потоки активны и основной поток завершается. См. « Сценарий зависает при выходе» при использовании atexit для завершения потоков .
Если вы создадите поток, подобный этому - myThread = Thread(target = function)
- а затем сделайте это myThread.start(); myThread.join()
. Когда инициируется CTRL-C, основной поток не выходит, потому что он ожидает этого блокирующего myThread.join()
вызова. Чтобы исправить это, просто установите тайм-аут для вызова .join (). Тайм-аут может быть сколь угодно длинным. Если вы хотите, чтобы он ждал бесконечно, просто установите действительно долгий тайм-аут, например 99999. Это также хорошая практика, myThread.daemon = True
чтобы все потоки выходили, когда завершается основной поток (не демон).
myThread.daemon = True
прекрасное решение этой проблемы.
Потоки демона уничтожаются без должного внимания, поэтому никакие инструкции финализатора не выполняются. Возможное решение - проверить, жив ли основной поток, а не бесконечный цикл.
Например, для Python 3:
while threading.main_thread().isAlive():
do.you.subthread.thing()
gracefully.close.the.thread()