Python如何处理信号?

6 投票
2 回答
2069 浏览
提问于 2025-04-16 19:58

在Python中处理信号的流程是怎样的呢?我设置了一个信号处理器,当信号发生时,Python是怎么调用我的函数的?这和C语言程序的处理方式一样吗?如果我在Python的C扩展中,信号会立即中断吗?


现在我明白了Python是如何处理信号的。当你通过信号模块设置一个信号时,这个模块会注册一个叫做signal_handler的函数(可以查看$src/Modules/signalmodule.c),它会设置你的处理器并把它标记为1(Handlers[sig_num].tripped = 1;),然后调用Py_AddPendingCall来通知Python解释器。接着,Python解释器会调用Py_MakePendingCalls,再调用PyErr_CheckSignals,这样就会在主循环中调用你的函数(可以查看$src/Python/ceval.c)。如果你想讨论这个问题,可以联系我:renenglish@gmail.com

2 个回答

0

看看这个 信号模块。如果你对一个Python脚本发送一个信号,我的理解是,如果这个脚本有处理这个信号的函数,它会先处理这个信号,并且可能有能力去处理和忽略某些信号。比如说,在收到一个SIGKILL信号时,你可以尝试先做一些清理工作,然后再结束程序,而不是直接杀掉它。

7

如果你使用信号模块在Python代码中设置了一个信号处理器,解释器只会在重新进入字节码解释器时才会运行这个处理器。也就是说,处理器不会立刻执行,而是会在信号发生时被放入一个队列中。如果此时代码正在执行C语言的代码(比如内置的或扩展模块),那么处理器就会被延迟执行,直到C代码把控制权交还给Python字节码解释器。这可能需要很长时间,而且你无法准确预测会花多长时间。

特别是如果你在使用交互模式并且启用了readline功能,那么你的信号处理器在你输入内容之前是不会运行的。这是因为输入的代码是在readline库中(也就是C语言代码),它在接收到完整的一行输入之前不会返回给解释器。

撰写回答