更新时间:2023-02-15 22:15:21
如果 wait
被中断,python 3.3 subprocess.call
实现会向其子进程发送 SIGKILL,它是由您的 Ctrl-C(SIGINT -> KeyboardInterrupt 异常)决定的.
The python 3.3 subprocess.call
implementation sends a SIGKILL to its child if its wait
is interrupted, which it is by your Ctrl-C (SIGINT -> KeyboardInterrupt exception).
因此,您会看到处理终端的 SIGINT(发送到整个进程组)的子进程与父进程的 SIGKILL 之间的竞争.
So, you see a race between the child process handling the terminal's SIGINT (sent to the whole process group) and the parent's SIGKILL.
来自 python 3.3 源代码,为简洁起见进行了
From the python 3.3 sources, edited for brevity:
def call(*popenargs, timeout=None, **kwargs):
with Popen(*popenargs, **kwargs) as p:
try:
return p.wait(timeout=timeout)
except:
p.kill()
p.wait()
raise
将此与 python 2 实现进行对比:
Contrast this with the python 2 implementation:
def call(*popenargs, **kwargs):
return Popen(*popenargs, **kwargs).wait()
多么令人不快的惊喜.当 wait
和 call
接口被扩展以适应超时时,这种行为似乎是在 3.3 中引入的.我认为这不正确,我已经提交了一个错误.
What an unpleasant surprise. It appears that this behavior was introduced in 3.3 when the wait
and call
interfaces were extended to accommodate a timeout. I don't find this correct, and I've filed a bug.