I am trying to implement a tray icon, that lets me control a process (jackd). Most notably
- I want to read the processes stdout and stderr for logging purposes
- I want to be able to kill the process from a menu entry of the main program
The killing is causing me headaches. I believe, when I read stdout and stderr I must do this in an extra thread/process to keep the icon responsive. So I used fork() to create a child process and called setsid()
on the child. That child process then invokes jackd using the subprocess
module
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"])
Now I was hoping that I could get my forked child process and jackd into the same process group, so I could kill both in one go, but to my surprise Popen
created a new process group and a new session:
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)
So, killing the child won't kill the grandchild and I don't see any clean way of making the grandchild's PID (5804) known to main
in order to kill it explicitly. I could probably use some signal trickery to have the dying child kill the grandchild, but I hesitate to do this.
I also cannot use setpgid
on the jackd process to force it into the child's process group, because its SID is different from my child's SID.
I believe I either
- have to convince Popen not to create a new session, or
- use a module with less magic than
subprocess
, but which still alows me to read stdout and stderr.
but I don't know how to do either. Admittedly my knowledge about process groups is somewhat limited.
/home/martin >python --version
Python 2.7.1
Update Oct 12
I found that the new session isn't created by python but by jackd
itself. When I replace jackd with xterm
, everything is fine.
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)
I also found this
these jack days calls setsid() to get itself established as a new process group leader
That only leaves the options to
- make jack's PID known to
main
and kill it explicitly, or - have the dying child kill kill jackd
Any advice on that?
.