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秒钟,比起voila,它不会“ do_stuff_before_python_terminates()”
我在这里做什么错了,如何解决即使在它的while循环中它立即退出并出现“ do_stuff_before_python_terminates()”的问题
更新说明:
它确实成功跳转到
except Exception as e:
logger.error("Exception")
do_stuff_before_python_terminates()
logger.log("sys.exit")
sys.exit(0)
它确实成功跳转到
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)
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)
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()
答案 0 :(得分:0)
您的do_stuff_before_python_terminates()
调用不正确(至少从我对信号和python的经验来看)。
在do_stuff_before_python_terminates()
和/或sigterm
函数中调用sigint
。
def do_stuff_before_python_terminates():
save_variables_in_mysql()
do_this_and_that()...
def sigterm(x, y):
do_stuff_before_python_terminates()
raise Exception()
def sigint(signal, frame):
do_stuff_before_python_terminates()
raise Exception()
请确保将do_stuff
函数放在sigterm和sigint函数上方。
答案 1 :(得分:0)
在main()中注册信号。例如:
def signal_handler(signal, frame):
print('\n')
sys.exit(0)
def main():
signal.signal(signal.SIGINT, signal_handler)
do_stuff_before_python_terminates()
直到底层C代码完成,信号才会触发。来自文档:“纯粹用C实现的长时间运行的计算(例如,在大文本正文上进行正则表达式匹配)可能会在任意时间内无中断运行,而不管收到任何信号。Python信号处理程序将被调用计算完成后。”
答案 2 :(得分:0)
来自Execution of Python signal handlers:
纯粹用C语言实现的长时间运行的计算(例如,在大文本正文上进行正则表达式匹配)可以在任意时间内连续运行,而不管收到任何信号。计算完成后,将调用Python信号处理程序。
这可能是导致您出现问题的原因。由于此限制(and others),用Python编写的信号处理程序除了在最简单的程序中外,很少表现出预期的作用。
如果您确实确实需要立即捕获信号,则可能需要使用调用Python代码的低级语言(例如C)为程序编写包装。