Якщо у мене є потік у нескінченному циклі, чи є спосіб його завершити, коли закінчується основна програма (наприклад, коли я натискаю Ctrl+ C)?
Відповіді:
Перевірте це питання. Правильна відповідь має чудове пояснення того, як правильно завершити потоки: чи є спосіб вбити Thread у 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 by setDaemon(True)
.
isDaemon()
і setDaemon()
старі геттери / сеттери (згідно пов'язаного з документом вище), просто використовуйте daemon=True
вthreading.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
вам функцію; разом з можливістю встановити потік як 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
є чудовим рішенням цієї проблеми.
.daemon=True
не в твердому розчині. Перевірте цю тему для пояснення: stackoverflow.com/a/20598791/5562492
Потоки демона вбиваються недобросовісно, тому будь-які вказівки завершувача не виконуються. Можливим рішенням є перевірка, чи основний потік живий, а не нескінченний цикл.
Наприклад, для Python 3:
while threading.main_thread().isAlive():
do.you.subthread.thing()
gracefully.close.the.thread()
Див. Перевірте, чи основна нитка все ще жива з іншого потоку .