(我正在使用Python 3.4.2)
我有一个脚本test.py,它处理SIGTERM等.但是,当其他脚本调用它时,信号处理是不正确的.
这是test.py:
#! /path/to/python3
import time
import signal
import sys
def handleSIG(signal, frame):
for i in range(10):
print(i)
sys.exit()
for sig in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT, signal.SIGHUP]:
signal.signal(sig, handleSIG)
time.sleep(30)
如果我只是调用“ test.py”并执行“ Ctrl C”,那么它将向控制台输出0,1,…,9.但是,如果我在另一个使用subprocess.call的脚本中调用test.py,则只会输出0.例如,这是另一个调用test.py的脚本:
import subprocess
cmd = '/path/to/test.py'
subprocess.call(cmd)
奇怪的是,使用subproces.Popen()可使此错误消失.
解决方法:
如果python 3.3 subprocess.call实现的等待被中断,则它会通过其Ctrl-C(SIGINT-> KeyboardInterrupt异常)向其子级发送SIGKILL.
因此,您看到在处理终端的SIGINT(发送到整个进程组)的子进程与父级的SIGKILL之间发生了争夺.
为了简化起见,从python 3.3来源编辑:
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实现进行对比:
def call(*popenargs, **kwargs):
return Popen(*popenargs, **kwargs).wait()
真是令人不快的惊喜.当扩展等待和调用接口以容纳超时时,似乎在3.3中引入了此行为.我找不到正确的答案,我有filed a bug.