我正在开发一个通过 Bottle 框架由网页控制的小型 python 应用程序。问题是我有时会在后台运行线程,但是如果 Bottle 实例被关闭,例如通过 Ctrl+C,它就会挂起,因为这些线程从未被告知退出。有没有办法捕捉 Bottle 服务器关闭并调用方法进行一些清理?
问问题
2080 次
4 回答
2
try
/ finally
:
# start threads here
try:
bottle.run(...) # or app.run(...)
finally:
# clean up (join) threads here
编辑:感谢@linusg 正确指出 try 块甚至不需要。最好只使用:
# start threads here
bottle.run(...) # or app.run(...)
# if we reach here, run has exited (Ctrl-C)
# clean up (join) threads here
于 2013-10-15T15:38:41.633 回答
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)
于 2013-10-15T13:28:21.420 回答
0
如果您的线程不需要优雅地关闭,那么只需让它们成为守护线程,您的进程将干净地退出而无需进一步更改。
可以将线程标记为“守护线程”。这个标志的意义在于,当只剩下守护线程时,整个 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.
注意,您问题的措辞暗示您真正的问题是它们导致您的进程在退出时挂起,而不是他们需要释放资源,但值得指出的是:
注意:守护线程在关闭时突然停止。它们的资源(如打开的文件、数据库事务等)可能无法正常释放。
于 2013-10-15T15:44:32.577 回答
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)
一旦您的服务器正常关闭或抛出异常(基本上退出 with 块),它将达到finally
条件并清理您的线程。
另一种选择是atexit。
于 2013-10-15T13:40:45.517 回答