当我试图终止一个python进程时,通过os.system
启动的子进程不会同时终止。
Killing child process when parent crashes in python和 Python Process won't call atexit (atexit看起来不适用于信号)
这是否意味着我需要自己处理这种情况?如果是,最好的方法是什么?
> python main.py
> ps
4792 ttys002 0:00.03 python run.py
4793 ttys002 0:00.03 python loop.py
> kill -15 4792
> ps
4793 ttys002 0:00.03 python loop.py
示例代码:
主.py
import os
os.system('python loop.py')
循环.py
import time
while True:
time.sleep(1000)
我做了一些实验,找到了一个可行的版本,但仍然混淆了逻辑。
import os
import sys
import signal
import subprocess
def sigterm_handler(_signo, _stack_frame):
# it raises SystemExit(0):
print 'go die'
sys.exit(0)
signal.signal(signal.SIGTERM, sigterm_handler)
try:
# os.system('python loop.py')
# use os.system won't work, it will even ignore the SIGTERM entirely for some reason
subprocess.call(['python', 'loop.py'])
except:
os.killpg(0, signal.SIGKILL)
在您的示例中,
kill -15 4792
将SIGTERM
发送到run.py
——它不向loop.py
(或其父shell)发送任何内容。SIGTERM
默认情况下不会传播到进程树中的其他进程。os.system('python loop.py')
至少开始两个进程shell和python
进程。您不需要它;使用subprocess.check_call()
,运行一个没有隐式shell的子进程。顺便说一下,如果你的subprocess is a Python script; consider importing it and running corresponding functions instead。os.killpg(0, SIGKILL)
向当前进程组发送SIGKILL
信号。shell为每个管道创建一个新的进程组(作业),因此父进程中的os.killpg()
对子进程没有影响(请参阅更新)。见How to terminate a python subprocess launched with shell=True。更新
似乎
os.system(cmd)
没有为cmd
创建新的进程组:因此,示例中的
os.system(cmd)
应该被os.killpg()
调用终止。不过,如果我在bash中运行它,它确实会为每个管道创建一个新的进程组:
相关问题 更多 >
编程相关推荐