LINUX.IE, website of the Irish Linux Users' Group
Tux rules!

   
Home
New Users
Articles
Download
Projects
Community
Vendors

  Print Version
Email to...
 
Archives:


planetILUG

Recent News

News Archive


Join the
ILUG
on FaceBook


Join the
ILUG
on LinkedIn


Join the
ILUG SETI
Group



















 
 :: Mailing Lists

[ILUG] Signal handling

[ILUG] Signal handling

Brian Foster blf at blf.utvinternet.co.uk
Wed Dec 8 04:40:09 GMT 2004


  | 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



More information about the ILUG mailing list
Read this without the formatting.
                                                                                                    

 

Hosted by HEAnet


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!
RSS Version
Powered by Dell