因此,我有以下代码(部分取自python文档):
import signal
def handler(signum, frame):
print 'Signal handler called with signal', signum
s = signal.signal(signal.SIGINT, handler)
some_fancy_code() # this code is using subprocess.Popen() to call another script
singal.signal(signal.SIGINT, s)我现在发现的是,如果我在程序中执行Ctrl+C,它将正确地进入处理程序并打印出来。现在,我想的是,在接收到Ctrl+C之后,我的处理程序将抑制默认处理程序,例如,我的subprocess.Popen将不会获得KeyboardInterrupt信号。但事实并非如此。
但是,当我们将“处理程序”替换为“signals.IG_IGN”时,这种传播永远不会发生。修改后的片段:
import signal
s = signal.signal(signal.SIGINT, signal.SIG_IGN)
some_fancy_code() # this code is using subprocess.Popen() to call another script
singal.signal(signal.SIGINT, s)这是因为SIG_IGN是用语言本身编写的某种“魔法”信号吗?或者也许有办法在我自己的处理程序中进行类似的抑制?
在阅读了一些关于堆栈溢出的问题后,我有点困惑。如果有人能告诉我为什么行为上有这么大的差异。
发布于 2014-02-18 15:31:22
这是信号的指定POSIX行为:
A child created via fork(2) inherits a copy of its parent's signal dis‐
positions. During an execve(2), the dispositions of handled signals
are reset to the default; the dispositions of ignored signals are left
unchanged.在第一种情况下,当您执行另一个脚本时,SIGINT处理程序将重置为另一个脚本中的默认处理程序(默认行为是终止进程)--当然,另一个脚本可以安装自己的处理程序并更改此行为。
但是,在第二种情况下,您已经将SIGINT配置为被忽略。此行为将传播到另一个脚本,如上面的定义所示。同样,另一个脚本可以通过安装自己的处理程序来改变这种行为。
因此,这与Python没有直接关系。它是底层操作系统的POSIX信号处理实现的预期行为。
如果您想知道fork()和execve()是什么,()将创建正在运行的进程(子进程)的副本,execve()将当前进程替换为另一个进程。这是subprocess.Popen()用于运行“另一个脚本”的底层机制:首先复制当前进程,然后将其替换为目标进程。
https://stackoverflow.com/questions/21856791
复制相似问题