Avoid race condition with Popen.send_signal

Jérôme jerome at jolimont.fr
Tue Jan 3 11:24:44 EST 2012


Tue, 3 Jan 2012 07:03:08 -0800 (PST)
Adam Skutt a écrit:

> On Jan 3, 4:38 am, Jérôme <jer... at jolimont.fr> wrote:
> > I have an application that can spawn a subprocess to play a beep. I want
> > it to kill the subprocess when exiting.
> 
> Why?  You shouldn't need to send a signal to tell the process to
> terminate: it should terminate when its stdin is closed or when it's
> done playing the beep in the first place.  If it doesn't, I would find
> a better way to play a beep in the first place.  What you're
> attempting to do sounds superfluous and unnecessary.

Probably. And somehow, I'd be glad.

Once the command (say beep) is called, it does terminate when done with the
beep. I just don't know if it can be stopped while playing and how.

(Perhaps the only clean way would be to call it several times by period of
10ms, for instance, to be able to stop at any time. But this makes the whole
thing much more complicated.)

> The only thing you ought to need to do is ensure that the child
> process is properly reaped if it terminates before your process
> terminates.

The application polls the ongoing child process until it has terminated, and
fetches its returncode. I hope this is "proper reaping".

The tutorial (http://docs.python.org/library/subprocess.html) didn't suggest
me to do anything more than that.
 
> Steps a and c are all that are necessary under standard SIGCHLD
> handling.  However, all of this should be entirely unnecessary in the
> first place.  

That's good news, because it seems a little bit ugly.

> Plus, I have a hard time imagining why something like 'gtk.gdk.beep()'
> isn't adequate for your needs anyway.

Short answer : I may well be, I just didn't know it.

I just looked at it quickly and it does not seem as flexible. Besides, beep
is just an example, I also use sox. And anyway, the whole thing is just a
training exercise I'm inflicting on myself, so I'm interested in solving the
subprocess issue for itself.

> The problem is being able to distinguish "process is a zombie" from
> "process doesn't exist" which both return ESRCH.  This is certainly
> possible with careful coding but I'm not sure I would bother except in
> the simplest programs.  Too many libraries do too many questionable
> things with signal handlers so I find it much safer and easier just to
> avoid the damn things whenever possible.

My small program _seems to_ work with the dirty hacks I already exposed. Yet,
I'd rather stay on the safe and easy side, especially in a future bigger
program. Therefore, I'm still interested in a better way to proceed.

Is there another way to tell beep (or sox) to stop before the end of the
beep ?

AFAIK, the only way to stop it on console is to feed it Ctrl+C. Should I use
communicate() for that ? How ? Apparently, the following does not work :

	process.communicate("\C-c")

It may well be that the dirtyness of my program comes from the choice of
external applications that don't allow nice termination through stdin. Or
perhaps is it possible and I haven't figured out how yet...

-- 
Jérôme



More information about the Python-list mailing list