Я работаю над небольшим приложением python, управляемым веб-страницей через фреймворк Bottle. Проблема в том, что иногда я выполняю потоки в фоновом режиме, но если экземпляр Bottle выключен, например, с помощью Ctrl + C, он просто зависает, потому что эти потоки никогда не говорят о выходе. Есть ли способ поймать выключение сервера бутылок и вызвать метод для очистки?Выполнить метод на выгрузке сервера Python Bottle
ответ
__del__
.
Что-то вроде:
class MyApp(bottle.Bottle):
def __del__(self):
# clean up threads here
# from here it's just business as usual
app = MyApp()
@app.route('/')
def home()
return 'hello, world.\n'
app.run('127.0.0.1', 8080)
Похоже, вы хотите контекстный менеджер:
from contextlib import contextmanager
#Code for server goes here
@contextmanager
def server_with_threads():
try:
spawn_thread_things()
yield MyServer()
finally:
close_thready_things()
#Or maybe here
with server_with_threads() as server:
server.run('127.0.0.1', 8080)
После того, как ваш сервер выключается корректно, или исключение (выход из с блоком, в основном) , то он попадет в состояние finally
и очистит ваши потоки.
Другой вариант: atexit.
try
/finally
:
# start threads here
try:
bottle.run(...) # or app.run(...)
finally:
# clean up (join) threads here
EDIT: Благодаря @linusg для правильно указывая на то, что блок попробовать даже не требуется. Лучше всего использовать:
# start threads here
bottle.run(...) # or app.run(...)
# if we reach here, run has exited (Ctrl-C)
# clean up (join) threads here
Нет. run() не генерирует исключение в Ctrl-C, поэтому try/finally не просто требуется. Вместо этого это сделало бы это: '# Начать потоки; bottle.run (...); #Clean up'! – linusg
@linusg Я просто подтвердил, что ты действительно прав. Ответ отредактирован, чтобы отразить ваше улучшение.Благодаря! –
Отлично, так что этот ответ действительно :) – linusg
Если потоки не нужно, чтобы закрыть грациозно, а затем просто сделать их daemon темы, и ваш процесс будет выходить чисто без дальнейших изменений.
Нить может быть помечена как «поток демона». Значение этого флага заключается в том, что вся программа Python завершается, когда оставлены только потоки демонов . Начальное значение наследуется от создающего потока. Флаг может быть установлен через свойство daemon.
t = threading.Thread(target=myfunc)
t.daemon = True
t.start()
# because t is a daemon thread, no need to join it at process exit.
NB, формулировка вашего вопроса предполагает, что ваша реальная проблема заключается в том, что они в результате чего ваш процесс, чтобы повесить на выходе, не то, что им нужно освободить ресурсы, но стоит отметить это:
Примечание: потоки демона внезапно останавливаются при выключении. Их ресурсы (такие как открытые файлы, транзакции базы данных и т. Д.) Не могут быть освобождены .
Возможно, вы можете просто установить обработчик сигнала для события CTRL-C, а затем выполнить очистку. http://docs.python.org/2/library/signal.html – Cillier
Хорошая мысль ... было бы здорово, если бы я мог справиться с любым отключением бутылок. –
Похоже, что вам нужны потоки «демона»? (См. Мой ответ ниже - и мои другие два. Извините, я увлекся этим соображением! :) –