我有一个包含3个主要组件的系统(一切都在Ubuntu14.04和Python 2.7上运行,不要太在意可移植性):
a)执行的一些二进制文件,我们将其称为runtime
,它将一些值写入{c}需要读取的stdout
和stderr
b)设置了环境并执行runtime
的启动器脚本,让我们称之为launcher
,它看起来像这样:
#!/bin/bash
#Needed by the runtime
export SOME_VAR=1234
source some_file.sh
#...
exec runtime --option1 $1 --option2 $2
c)服务器,它处理远程请求并在远程客户端请求时调用launcher
。服务器是用python编写的,需要从(a)中读取stdX
。我正在使用子流程模块调用launcher
:
# When calling the launcher script:
cmd = "launcher value1 value2"
p = subprocess.Popen(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
shell=True)
# read p.stdout ...
这创建了2个新进程,1个用于launcher
脚本(例如pid:10000),另一个用于runtime
(例如pid:10001),运行htop
{{1} }}显示类似于此的内容:
tree
在某些时候,PID ... Command
12345 ... python server.py
10000 ... |- /bin/sh -c ./launcher value1 value2
10001 ... |- runtime --option1 value1 --option2 value2
想要停止server
流程(通过发送runtime
)
SIGTERM
问题是这只会导致# When trying to stop the runtime:
os.kill(p.pid, signal.SIGTERM)
# Have also tried with p.terminate(), same results.
进程(pid:10000)无效,导致launcher
无限期执行。每当runtime
请求SIGTERM
必须接收此信号以停止并正常退出时,我想将runtime
正确地传播到server
,否则会产生数据损坏)
我尝试使用runtime
来杀死整个进程组,但它也会杀死os.killpg(...)
(显然)。
如何将SIGTERM信号正确传播到子子流程?
答案 0 :(得分:0)
以这种方式使用流程组:
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
shell=True, preexec_fn=os.setpgrp)
os.killpg(os.getpgid(p.pid), signal.SIGTERM)