在基于Gevent的应用程序中捕捉术语信号

2024-10-01 13:27:53 发布

您现在位置:Python中文网/ 问答频道 /正文

我用Python编写了一个基于Gevent的简单守护进程。守护进程在存在之前需要进行一些清理,因此它必须能够处理术语signal,执行其清理并优雅地退出。在一个不基于Gevent的单线程守护进程中,我使用Python的signal模块为术语signal设置了一个信号处理程序。{user-defined}抛出一个名为的异常处理程序。守护进程的主线程只需捕获TermSignal异常,进行清理并退出。在

当我试图在基于Gevent的守护进程中实现它时,这个解决方案并没有如预期的那样工作。守护进程有一个主greenlet,它对workers greenlet调用joinalljoinall调用被包装在try/except块中,该块捕获keyboardInterrupt,该块允许守护进程在不进行守护程序的情况下运行时执行清理。然而,当我实现上述解决方案并向进程发送一个术语信号时,我可以在控制台窗口中看到其中一个worker greenlet引发了TermSignal异常,而不是主greenlet。尽管我调用了joinall,并将raise_error参数设置为True,但这个未捕获的异常并没有影响到主greenlet。结果是一个工作greenlets由于异常而崩溃,但是守护进程根本没有退出。在


Tags: 模块程序处理程序signal进程gevent解决方案greenlet
1条回答
网友
1楼 · 发布于 2024-10-01 13:27:53

我搜索了一下,找到了解决办法。正如前面提到的here,Gevent的monkey补丁没有修补Python内置的signal.signal函数。为了使我的解决方案有效,主greenlet必须调用gevent.signal而不是{}来设置处理程序。另外,gevent.signal需要不接受参数的处理程序函数,而不像{}期望处理程序函数接受2个参数。既然我不在乎这些论点,我就把术语处理程序改成这样:

def _term_handler(*_):
    raise TermSignal()

这样就可以在Gevent应用程序和常规Python应用程序中使用相同的术语handle。尽管在这两种情况下都可以使用相同的处理程序,但它需要由适当的函数(signal.signalgevent.signal)来设置

相关问题 更多 >