我在基于Gevent的Python中编写了一个简单的守护进程。守护进程在它存在之前需要进行一些清理,因此它必须能够处理TERM信号,对其进行清理并优雅地退出。在一个不基于Gevent的单线程守护进程中,我使用Python的信号模块为TERM信号设置了一个信号处理程序。信号处理程序抛出一个用户定义的异常,称为TermSignal
。守护进程的主线程可以捕获TermSignal异常,进行清理并退出。在基于Gevent的应用程序中捕获TERM信号
当我试图在基于Gevent的守护程序中实现它时,此解决方案没有按预期工作。守护进程有一个主要的greenlet,在工人greenlets上调用joinall
。 joinall
调用被封装在try/except块中,该块捕获KeyboardInterrupt
,它允许守护进程在其不进行守护进程运行时执行其清理操作。但是,当我实现上述解决方案并向进程发送TERM信号时,我可以在控制台窗口中看到其中一个worker greenlet引发了TermSignal
异常,而不是主greenlet。这个未捕获的异常并没有影响主greenlet,尽管面对我称为joinall
与raise_error
参数设置为True
。结果是由于例外情况,其中一个工人小程序崩溃,但守护进程根本没有退出。