我试图实现一个托盘图标,它可以让我控制一个进程(jackd)。最值得注意的是如何杀死python中的分叉子及其jackd子进程
- 我想读的过程输出和错误进行日志记录
- 我希望能够从主程序菜单项杀死进程
杀伤引起我头痛。我相信,当我阅读stdout和stderr时,我必须在一个额外的线程/进程中做到这一点,以保持图标的响应。所以我用fork()来创建一个子进程,并在子进程上调用setsid()
。然后,该子进程调用jackd使用subprocess
模块
from subprocess import PIPE, STDOUT, Popen
def runAndLog(self, cmd):
po = Popen(cmd, stdout=PIPE, stderr=STDOUT)
line = po.stdout.readline()
while line:
print(line.rstrip())
line = po.stdout.readline()
self.runAndLog(["jackd","-R", "-P80", "-t5000", "-dfirewire", "-r44100", "-p256", "-n3"])
现在,我希望我能得到我的派生的子进程和jackd到同一个进程组,这样我就可以同时杀死一气呵成,但让我吃惊Popen
创建一个新的进程组和一个新的会话:
PID PPID PGID SID COMMAND
5790 5788 5788 31258 python (parent, main)
5791 5790 5791 5791 python (forked child after setsid - ok)
5804 5791 5804 5804 jackd (grandchild created by Popen)
所以,造成孩子不会杀死孙子,我看不出在作出已知main
孙子的PID(5804)的任何清洁方式为了明确地杀死它。我可能会用一些信号欺骗手段让垂死的孩子杀死孙子,但我毫不犹豫地这样做。
我也不能在jackd进程上使用setpgid
来迫使它进入子进程组,因为它的SID与我孩子的SID不同。
我相信我要么
- 必须说服POPEN不是创建一个新的会话,或
- 使用一个模块与魔法小于
subprocess
,但仍alows我读输出和错误。
但我不知道该怎么做。无可否认,我对过程组的了解有限。
/home/martin >python --version
Python 2.7.1
更新10月12日
我发现新的会话不被蟒蛇创建,而是由jackd
本身。当我用xterm
替换jackd时,一切都很好。
PID PPID PGID SID COMMAND
12239 4024 12239 4024 python (parent, main)
12244 12239 12244 12244 python (forked child after setsid - ok)
12249 12244 12244 12244 xterm (grandchild has same PGID and SID - ok)
我还发现this
这些插孔天调用setsid()得到确立了其作为一个新的 工艺组组长
这只是离开选项
- 使jack的PID已知
main
和明确杀死它,或 - 有垂死的孩子杀杀人jackd
上有什么建议?
。
此答案有帮助吗? http://stackoverflow.com/a/4791612 –
这几乎是我在做什么。但是,我发现问题确实是自己而不是python。我会相应地更新我的问题。 –
为什么不直接使用线程,直接控制'jack'?为什么你要独立制作一个子进程来控制实际的命令呢?使它变得如此复杂的假设好处是什么? –