| From: jm at jmason.org (Justin Mason)
| Date: Tue, 07 Dec 2004 11:35:28 -0800
|
| Dale Dunlea writes:
| > It's an audio app and the child process is the actual audio player
| > program. Killing it an restarting is a little messy. Hence the desire
| > to let it play out even though the process that spawned it has died.
|
| I think you'd be better off coming up with a way to kill/restart cleanly
| so that the child isn't left running when the parent dies.
I tend to agree, but should point out one issue:
killing/restarting something emitting audio will
cause a “glitch” in the sound (besides probably
restarting it from the beginning), which is not
necessarily desirable. whether or not this is
Dale's concern is unknown (“a little messy“ can
mean many things).
| The general UNIX idiom is that if you fork a process, and the parent is
| killed with SIGINT or SIGTERM, the parent kills the child in response,
| before it itself cleans up and exits. This is the general case; it
| applies in most cases, apart from "nohup" or when starting a daemon.
no.
daemons that manage children, or tightly-coupled
coprocesses, may do this, but otherwise no, it is
neither the idiom nor common. what _is_ the idiom
is the child inherits the signal handling of the
parent. (until an execve(2), obviously, when all
caught signals are reset to the default; ignored
signals are still ignored (generally, albeit SIGCHLD
is, AFAICR, on some systems, reset to default).)
actually, inheriting happens automatically; the
idiom is not doing stupid things that break it
(e.g., reseting ignored signals).
“but how“, I hear people asking, “is ^C handled?
when I ^C a pipe, the entire pipe dies. surely,
the shell, which is ‘controling’ the pipe, must
be forwarding the signal (SIGINT)?”
*sigh* common misconception.
signals generated from the keyboard --- e.g., ^C
causing a SIGINT --- are sent to all processes in
the process group currently associated with the
terminal (keyboard). all the processes which
form the pipe are in the same process group, and
if that pipe is in the foreground, that process
group is the one associated with the keyboard.
(that is, in fact, what “foreground” means.)
the shell may or may not be in the foreground
process group --- it varies depending on shell
and system --- the shell's only involvement is
to make the terminal-process group association.
(except on very old ancient Unix systems that
did not have job control, where the association
was automagic.)
upshot is every process in the pipe is responsible
for its own signal handling. which is the idiom.
in most cases, this means doing exactly nothing;
the process has inherited (from the shell) the
correct behaviour.
| However, if you're still keen to keep the child running after the parent
| has exited -- what you can do is the following:
I concur with what Justin suggests below, but will
also throw in one or two caveats ....
| - when starting the child: record its PID in a pidfile somewhere on-disk
|
| - when a new parent process is started: check that pidfile to see if a
| child is running
actually, all the pidfile means is the pidfile
has not been deleted. and all not having a
pidfile means is that it may have been deleted.
there is, at best, a weak association between
having a pidfile and the _correct_ process with
that PID existing.
| - read the PID from that file, and use kill(0, pid) to see if the
| process with that ID exists
no, not to see if “the” process with that PID exists;
but to see if _a_ process with that PID exists.
as Pádraig pointed out, this is not robust, albeit it
is a common idiom, and does “work” most of the time.
| - do not use SIGCHLD to track if the child is alive or dead, since that
| will not work if the child's parent != current process
correct. using ptrace(2) here --- which gets around
this issue --- is a hack with some nasty side-effects.
| - instead use kill(0, pid) periodically to poll the child and ensure
| it's still running. if kill returns the error ESRCH, the child has
| exited and you can deal with that (restart a new one or whatever).
there are many variations on what Justin suggests,
such as using an LOCK_EX flock(2), but no(?) general
scheme is completely robust --- superuser, at least,
can “break“ all(?) of them. whether or not that is
a problem depends on circumstances.
cheers!
-blf-
--
Experienced (20+ years) kernel engineer: | Brian Foster Montpellier,
· Unix, ChorusOS, others; | blf at utvinternet.ie FRANCE
· IDL, automated testing, process, &tc. | Stop E$$o (ExxonMobile)!
Résumé: http://www.blf.utvinternet.ie | http://www.stopesso.com
Maintained by the ILUG website team. The aim of Linux.ie is to
support and help commercial and private users of Linux in Ireland. You can
display ILUG news in your own webpages, read backend
information to find out how. Networking services kindly provided by HEAnet, server kindly donated by
Dell. Linux is a trademark of Linus Torvalds,
used with permission. No penguins were harmed in the production or maintenance
of this highly praised website. Looking for the
Indian Linux Users' Group? Try here. If you've read all this and aren't a lawyer: you should be!