Python SIGINT SIGTERM不会立即退出while循环

Python SIGINT SIGTERM不会立即退出while循环,python,sigint,sigterm,Python,Sigint,Sigterm,我在Docker容器中使用Python 当我通过终端tty执行ctrl+c或停止图像时 python确实停止了,但并不总是成功 “在python终止()之前进行填充” 原因是,当python随机出现在while循环中时,我运气不佳,它没有退出,而是停留在while循环中,执行其他操作,并且没有成功终止 Docker只需等待10秒就可以杀死容器,而且瞧,它不会“在python终止()之前进行填充” 我在这里做错了什么,如何解决这样一个问题:即使在while循环中,它也会立即退出并“在python终

我在Docker容器中使用Python

当我通过终端tty执行ctrl+c或停止图像时 python确实停止了,但并不总是成功 “在python终止()之前进行填充”

原因是,当python随机出现在while循环中时,我运气不佳,它没有退出,而是停留在while循环中,执行其他操作,并且没有成功终止

Docker只需等待10秒就可以杀死容器,而且瞧,它不会“在python终止()之前进行填充”

我在这里做错了什么,如何解决这样一个问题:即使在while循环中,它也会立即退出并“在python终止()之前完成任务”

最新解释:

如果python出现错误 它确实成功地跳转到

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)
如果停止容器或使用ctrl+c,python不在while循环中 它确实成功地跳转到

except Exception as e:
    logger.error("Exception")
    do_stuff_before_python_terminates()
    logger.log("sys.exit")
    sys.exit(0)
如果停止容器或使用ctrl+c,python处于循环中 我需要的是,每当我停止容器或执行ctrl+c(sigterm+sigint)时,它都会立即跳出while循环
Docker会在10秒后杀死容器,因此python只有10秒的时间退出,其效果是当python处于循环中时,它不会在python终止()之前进行填充。

您的
在python终止()之前进行填充。
调用不正确(至少从我对信号和python的经验来看)

sigterm
和/或
sigint
函数中,在python\u终止()之前调用
do\u stuff\u

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)
确保将
do_stuff
函数置于sigterm&sigint函数之上

  • 在main()中注册信号。例如:

    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()
    
  • 直到低级C代码完成,信号才会触发;从文档中可以看出:“纯用C语言实现的长时间运行的计算(例如在大量文本上进行正则表达式匹配)可以不间断地运行任意时间,而不管接收到什么信号。计算完成后将调用Python信号处理程序。”

  • 发件人:

    纯用C语言实现的长时间运行的计算(例如在大量文本上进行正则表达式匹配)可能会在任意时间内不间断地运行,而与接收到的任何信号无关。计算完成后将调用Python信号处理程序

    这可能是您的问题的原因。由于这个限制(),用Python编写的信号处理程序除了在最简单的程序中外,很少有预期的行为


    如果您确实需要立即捕获信号,则可能需要用调用Python代码的低级语言(如C)为程序编写包装器。

    这可能是编写信号处理程序的正确方法,但我想了解原始代码的错误。我添加了更多信息,感谢您的回答我很感激,但您的回答无助于两种可能的解释:从
    main()调用的代码安装自己的信号处理程序或从main调用的代码捕获
    异常,我修改了结构,使其更具可读性,这可能是它看起来像是主函数中的信号的原因,您能否提供解决方案?我的意思是,调用的某些函数可能会干扰您所依赖的异常引发和捕获机制。可能不是这样,我不知道,但您可以通过最小化代码来测试和排除它。文本
    except:
    Exception
    是否存在于您的代码中的任何其他地方?这两种方法中的任何一种都可能在信号生成的异常到达处理程序之前捕获该异常,该处理程序在python终止()之前执行
    do\u stuff\u。是-如果您的代码当前正在另一个try/except中执行,则第一次有机会捕获
    异常。除
    之外的所有
    都需要使用最具体的异常名称,这样它们就不会捕获不应该捕获的内容。如果在代码进入main()之前将它们全局注册,有什么区别?我只有跳出while loops的问题没有“全局”——如果你有一个main(),脚本从那里开始,然后从那里开始。我的代码从上到下运行,然后在我告诉他的代码末尾跳入main,在任何函数之外,我都会注册sigint和sigterm处理程序,就像我引用的示例代码源一样:谢谢,但这对我来说是不可能的。我不能用C编写代码,我需要在每个sigterm或sigint(shutdown或ctr+l)上的python_终止()之前运行dou_stuff_。
    
    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)
    
    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()
    
        def signal_handler(signal, frame):
                print('\n')
                sys.exit(0)
    
        def main():
            signal.signal(signal.SIGINT, signal_handler)
            do_stuff_before_python_terminates()