2013-10-14 2 views
1

Я работаю над небольшим приложением python, управляемым веб-страницей через фреймворк Bottle. Проблема в том, что иногда я выполняю потоки в фоновом режиме, но если экземпляр Bottle выключен, например, с помощью Ctrl + C, он просто зависает, потому что эти потоки никогда не говорят о выходе. Есть ли способ поймать выключение сервера бутылок и вызвать метод для очистки?Выполнить метод на выгрузке сервера Python Bottle

+0

Возможно, вы можете просто установить обработчик сигнала для события CTRL-C, а затем выполнить очистку. http://docs.python.org/2/library/signal.html – Cillier

+0

Хорошая мысль ... было бы здорово, если бы я мог справиться с любым отключением бутылок. –

+0

Похоже, что вам нужны потоки «демона»? (См. Мой ответ ниже - и мои другие два. Извините, я увлекся этим соображением! :) –

ответ

0

__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) 
0

Похоже, вы хотите контекстный менеджер:

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.

2

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 
+0

Нет. run() не генерирует исключение в Ctrl-C, поэтому try/finally не просто требуется. Вместо этого это сделало бы это: '# Начать потоки; bottle.run (...); #Clean up'! – linusg

+1

@linusg Я просто подтвердил, что ты действительно прав. Ответ отредактирован, чтобы отразить ваше улучшение.Благодаря! –

+0

Отлично, так что этот ответ действительно :) – linusg

0

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

Примечание: потоки демона внезапно останавливаются при выключении. Их ресурсы (такие как открытые файлы, транзакции базы данных и т. Д.) Не могут быть освобождены .