【发布时间】:2018-12-21 23:20:59
【问题描述】:
def do_stuff_before_python_terminates():
save_variables_in_mysql()
do_this_and_that()...
def main():
do stuff
while loops ect...
def sigterm(x, y):
raise Exception()
def sigint(signal, frame):
raise Exception()
signal.signal(signal.SIGINT, sigint)
signal.signal(signal.SIGTERM, sigterm)
try:
while True:
main()
except Exception as e:
logger.error("Exception")
do_stuff_before_python_terminates()
logger.log("sys.exit")
sys.exit(0)
我在 Docker 容器中使用 Python
当我通过终端 tty 执行 ctrl+c 或停止图像时 python确实停止并且并不总是成功 “do_stuff_before_python_terminates()”。
原因是,当 python 随机处于 while 循环中时,我没有运气,它不会退出,它会停留在 while 循环中并继续执行其他操作,并且不会成功终止。
Docker 在杀死容器之前只等待 10 秒,然后瞧,它没有“do_stuff_before_python_terminates()”
我在这里做错了什么,如何解决即使在while循环中它也会立即退出并且“do_stuff_before_python_terminates()”的问题
更新说明:
如果python抛出错误
确实成功跳转到
except Exception as e:
logger.error("Exception")
do_stuff_before_python_terminates()
logger.log("sys.exit")
sys.exit(0)
如果我停止容器或使用 ctrl+c 并且 python 不在 while 循环中
确实成功跳转到
sigterm() or sigint() -> then raise an Exception() -> then jumps to
except Exception as e:
logger.error("Exception")
do_stuff_before_python_terminates()
logger.log("sys.exit")
sys.exit(0)
如果我停止容器或使用 ctrl+c 并且 python 在循环中
it does stay in the loop
do stuff
do stuff
do stuff
after nearly 20-30seconds
sigterm() or sigint() -> then raise an Exception() -> then jumps to
except Exception as e:
logger.error("Exception")
do_stuff_before_python_terminates()
logger.log("sys.exit")
sys.exit(0)
我需要的是,当我停止容器或执行 ctrl+c (sigterm + sigint) 时,它会立即跳出 while 循环
sigterm() or sigint() -> then raise an Exception() -> then jumps to
except Exception as e:
logger.error("Exception")
do_stuff_before_python_terminates()
logger.log("sys.exit")
sys.exit(0)
Docker确实会在10秒后杀死容器,所以python只有10秒的时间退出,效果是当python处于循环中时它永远不会do_stuff_before_python_terminates()
【问题讨论】:
-
两种可能的解释:从
main()调用的代码安装了自己的信号处理程序,或者从main 调用的代码捕获了Exception。 -
对不起,不知道你的意思,我将结构更正为更具可读性,也许这就是它看起来像信号在主要功能中的原因,你能提供一个解决方案
-
我的意思是,某些被调用的函数可能会干扰您所依赖的异常引发和捕获机制。也许不是这样,我不知道,但是您可以通过最小化代码来测试并排除它。
-
文本
except:或except Exception是否存在于代码中的其他任何位置?其中任何一个都可能在信号生成的异常到达执行do_stuff_before_python_terminates()的处理程序之前捕获它。 -
是的 - 如果您的代码当前正在另一个 try/except 中执行,则第一次有机会捕获
Exception。您所有的excepts 都需要尽可能使用最具体的异常名称,这样他们就不会捕获不应该捕获的东西。