home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.unix.wizards
- Path: sparky!uunet!wupost!sdd.hp.com!caen!hellgate.utah.edu!fcom.cc.utah.edu!cs.weber.edu!terry
- From: terry@cs.weber.edu (A Wizard of Earth C)
- Subject: Re: Queueing of signals
- Message-ID: <1992Aug14.072625.26349@fcom.cc.utah.edu>
- Keywords: SIGCHLD, signals, queueing, sigvec
- Sender: news@fcom.cc.utah.edu
- Organization: Weber State University (Ogden, UT)
- References: <1992Aug13.160824.11077@bwdls61.bnr.ca>
- Date: Fri, 14 Aug 92 07:26:25 GMT
- Lines: 142
-
- You know, if I had any sense, I'd be going to bed right this instant...
-
- In article <1992Aug13.160824.11077@bwdls61.bnr.ca> gwaters@bwdls139.bnr.ca (Glenn Waters) writes:
- >I have a program that seems to lose SIGCHLD signals. There are two (or more)
- >processes that die simultaneously -- thus generating two SIGCHLDs
- >to the parent. I only seem to get the first SIGCHLD.
- >
- >Are the signals queued? I believe not.
- >
- >What is the correct method of catching the subsequent child deaths that are
- >not queued?
-
- 1) Signals aren't queued
- 2) POSIX signals aren't queued (they almost say they are but not quite)
- 3) You can't catch multiple instances of signals which occur prior/during
- handler invocation, since a signal is a persistant condition, not an
- event. It may be set by an event (the event itself having been queued),
- but how many time a bit was set high is undetectable.
-
-
- HOWEVER:
-
- For child deaths, you CAN sneaky around it:
-
-
- /*
- * My routine macduff, which handles at least one SIGCLD per cluster of
- * them due to the nature of signals...
- */
-
- int the_bell_tolled = 0;
-
- macduff()
- {
- /*
- * Mother! I am killed! --MacDuff in "Macbeth" by W. Shakespere;
- * look it up on your NeXT.
- */
- the_bell_tolled = 1;
- }
-
- /*
- * My initialization, living somewhere...
- */
- ...
- signal( SIGCLD, macduff);
- ...
-
- /*
- * My main loop, living somewhere (preferrably after my initialization 8-)...
- */
- for(;;)
- ...
- /*
- * Check for the bell...
- */
- if( the_bell_tolled) {
- /*
- * "Ah! I see you have the machine that goes *BING*!"
- * - J. Cleese, "The Meaning of Life"
- */
- the_bell_tolled = 0; /* shut off the bell BEFORE reaping*/
- grim_reaper(); /* ...ask for whom the bell tolled*/
- ...
- }
- }
-
- /* NOTREACHED*/
-
- exit( 0); /* the end of my program*/
-
-
- /*
- * My routine grim_reaper, who takes the souls of the dead child processes
- * to silicon heaven (so to speak, and only in the most general terms).
- *
- * "No silicon heaven!?! Ridiculous! Where would all the calculators go?"
- * -- Kryten, "Red Dwarf"
- */
- grim_reaper()
- {
- int pid; /* pid_t for puritans*/
- int st;
-
- /*
- * You may have to use a different "scythe": ie: wait3 instead of
- * waitpid, or whatever you have instead that returns the pid and
- * status of a reaped child process if the is one but doesn't
- * hang otherwise.
- */
- while( ( pid = waitpid( -1, &st, WNOHANG)) > 0) {
- printf( "Child PID %d exited with %d\n", pid, st);
- ...
- }
- }
-
-
-
- What happens is that one or more child deaths result in a signal
- SIGCLD being caught by macduff. He sets a flag (the_bell_tolls). Then
- SIGCLD's are allowed to happen again. This way, regardless of the number
- of SIGCLDs, you always know that there was 0 > count < n of them. Since
- the handler is not in operation at the time that the actual handling is
- to [conditionally] occur, handling the SIGCLD's will not cause them to
- be blocked for the duration. By setting the flag to zero before waking
- up Bill and Ted's friend to deal with the handling, we make sure that
- anything caught while handling will result in another call to the handler,
- and that there is thus not a window where we can "miss" one or more SIGCLDs
- (SIGChiLDren?). This translates the SIGCLD from a "one or more processes
- have died" *flag* into a "better see how many died" *event*. Mr. Reaper
- then goes out and reaps each of the child processes. If you were interested
- in precisely which child died (ie: for some reason your children were not
- homogeneous processes, like fork/exec), you have the PID of the dead child,
- and can do a reverse-lookup to compare against an array of child PIDs (which
- are probably structure element members) which you cleverly saved off when
- you forked, and can act accordingly.
-
- Delayed handling of signals is useful in any case where the cause
- of the signal is determinable and persistant (SIGPOLL on a stream head,
- for instance, where determination of the culprit can be made using the
- select/poll system calls), but not as a general mechanism. This means you
- should probably not use multiple signal generators for which you are handling
- signals (ie: child deaths and stream data available) in the same program
- unless you can be guaranteed of a signal being blocked for delivery instead
- of ingnored when you're handling the other signal.
-
- Signals are queued in the POSIX 1003.4 spec, but this is still
- subject to change and probably wont be frozen one way or the other until
- late 93/early 94; until then, we'll all have to just limp along...
-
-
- Terry Lambert
- terry_lambert@gateway.novell.com
- terry@icarus.weber.edu
- ---
- Any opinions in this posting are my own and not those of my present
- or previous employers.
- --
- -------------------------------------------------------------------------------
- terry@icarus.weber.edu
- "I have an 8 user poetic license" - me
- -------------------------------------------------------------------------------
-