返回

当 Python .exe 遇到 NSSM 服务停止时,如何传递信号?

windows

停止 NSSM 服务时向 Python .exe 发送信号

问题

当 Python 程序转换为 .exe 文件(使用 auto_py_to_exe)后,它将无法再接收由 Ctrl+C 按键组合产生的 SIGINT 信号。因此,我们需要找到替代信号来在停止服务时通知程序。

解决方案:NSM 服务停止时发送的信号

Windows NSSM 服务管理器在停止服务时发送以下信号:

  • SIGTERM :通知进程正常终止。
  • SIGKILL :强制终止进程,不会执行任何清理操作。

在 Python 程序中,我们可以使用 signal 模块注册信号处理程序来捕获这些信号。

代码修改

修改后的 Python 程序如下:

import logging
import time
import signal
import sys

class ClarkeTest:
    
    def __init__(self):
        # Configure logging
        logging.basicConfig(filename='clarke_test.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
        
        # Set up signal handler for SIGTERM and SIGKILL
        signal.signal(signal.SIGTERM, self.signal_handler)
        signal.signal(signal.SIGKILL, self.signal_handler) 
    
    def signal_handler(self, sig, frame):
        logging.info("Received {}. Exiting...".format(sig))
        sys.exit(0)
        

    def main(self):

        while True:
            logging.info("Hello Victor")
            time.sleep(5)

if __name__ == "__main__":
    ClarkeTest().main()

结论

通过使用 signal 模块注册 SIGTERMSIGKILL 信号处理程序,我们现在可以确保即使在程序已转换为 .exe 并作为 NSSM 服务运行的情况下,也能在停止服务时收到信号并执行清理操作。

常见问题解答

1. SIGTERM 和 SIGKILL 之间的区别是什么?

SIGTERM 是一个通知信号,允许进程执行清理操作并正常终止,而 SIGKILL 是一个强制终止信号,不会执行任何清理操作。

2. 如何在 Windows 中启动 NSSM 服务?

使用 nssm 命令 seguito de los argumentos apropiados, como nssm install

3. 除了 SIGTERM 和 SIGKILL 之外,还有哪些其他信号可以用来停止 NSSM 服务?

没有其他信号可以用来停止 NSSM 服务。

4. 如果信号处理程序中的代码抛出异常会怎样?

如果信号处理程序中的代码抛出异常,进程将收到默认操作,即正常终止(SIGTERM)或强制终止(SIGKILL)。

5. 如何调试信号处理程序?

可以使用 pdb 模块设置断点并逐步调试信号处理程序。