开发中遇到一个问题,主进程调用 subprocess 后,在关闭process是出现问题
网上查看方法发现,使用subprocess的返回 process类似的terminate()方法,甚至用os.kill()方法,只能杀死创建的当前进程,但是其子孙进程会被 init(unix)或者systemd(ubuntu) 接管, 成为守护进程。
正确方法:
第一步: subprocess中增加 preexec_fn=os.setsid
preexec_fn 参数,它接受一个回调函数,并在 fork 之后 exec 之前的间隙中执行它
setsid() 可以使创建的进程成立一个独立的进程组。
def execute_cmd_no_ret(cmd):
"""
Execute command used subprocess, no timesout check, no std return.
"""
process = subprocess.Popen(cmd, shell=True, executable="bash", stdout=None, stderr=None, preexec_fn=os.setsid)
return process
第二步:关闭进程组,os.killpg
关闭时候调用进程组关闭:
def stop_fm_process(self):
os.killpg(self.pp.pid, signal.SIGTERM) #给进程组的所有进程发结束信号
self.pp.terminate()
self.pp.wait() #回收创建进程,放置成为僵尸
如此subprocess.Popen 创建进程后,该进程再次创建的子子孙孙都可以有效关闭