Avoid race condition with Popen.send_signal

Adam Skutt askutt at gmail.com
Tue Jan 3 12:58:35 EST 2012


On Jan 3, 10:09 am, Jérôme <jer... at jolimont.fr> wrote:
> Tue, 3 Jan 2012 06:12:59 -0800 (PST)
> Adam Skutt a écrit:
>
> > The conservative approach is to use another IPC mechanism to talk to
> > the process, such as a pipe or a socket.  Why are you trying to send
> > the child process SIGINT in the first place?
>
> Say, you've got an application that plays a sound for a few seconds, using an
> external program for that (beep, sox). If you close the application, you want
> the sound to stop as well.

If your application wants to play audio and terminate playing audio
early, it really should use an audio library and play the sound
directly.  Especially if you're playing so many sounds in such a
fashion you need to terminate them.  If you're playing a single beep
or short sound, then who really cares if it occurs slightly after your
processes ends?  GStreamer is one such library for sound processing
though it may be more complicated than you need.

> Should I try something like this ?
>
>         communicate(input="Ctrl+C")
>
> (I'd need to figure out how to write Ctrl+C...)
>
> Would that be cross-platform ?
>

No, that won't work at all.  'Ctrl-C' is a magic indicator to the
terminal driver to send SIGINT to the appropriate processes: it never
actually appears as an input and output character to a program unless
it's controlling the terminal in raw mode (where it loses its special
meaning).  If you're really insistent on using the sox(1) command-line
tools to play your sounds, then you'll have to send SIGINT or SIGTERM
in order to tell it to terminate (which can be done just by calling
the terminate() method).

Which is fine and will probably work OK subject to three restrictions:
1. Nothing in your application modifies the default handling of
SIGCHLD.  This means that the child process appears as a zombie (e.g.,
via 'ps ax') until the parent calls poll() or wait() methods to reap
it.
2. You only send signals while the process is alive or a zombie: once
the poll() or wait() methods  return something other than None, you
cannot safely send anymore signals.
3. You trap any errors returned by the send signal call.

Adam



More information about the Python-list mailing list