Eri*_*a L 3 python subprocess signals python-3.x
(我使用的是 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)
Run Code Online (Sandbox Code Playgroud)
如果我只是调用“test.py”并执行“Ctrl+C”,那么它会在控制台上打印 0,1,...,9。但是,如果我使用 subprocess.call 在另一个脚本中调用 test.py,则只会打印 0。例如,这是另一个调用 test.py 的脚本:
import subprocess
cmd = '/path/to/test.py'
subprocess.call(cmd)
Run Code Online (Sandbox Code Playgroud)
奇怪的是,使用 subproces.Popen() 会使这个错误消失。
python 3.3subprocess.call实现会在它的子进程wait被中断时向它的子进程发送一个 SIGKILL ,这是你的Ctrl- C(SIGINT -> KeyboardInterrupt 异常)。
因此,您会看到处理终端的 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
Run Code Online (Sandbox Code Playgroud)
将此与 python 2 实现进行对比:
def call(*popenargs, **kwargs):
return Popen(*popenargs, **kwargs).wait()
Run Code Online (Sandbox Code Playgroud)
多么令人不快的惊喜。当wait和call接口被扩展以适应超时时,似乎这种行为是在 3.3 中引入的。我不认为这是正确的,我已经提交了一个错误。
| 归档时间: |
|
| 查看次数: |
3429 次 |
| 最近记录: |