Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 9 Jul 1996 14:42:22 -0700 (MST)
From:      Terry Lambert <terry@lambert.org>
To:        brandon@tombstone.sunrem.com (Brandon Gillespie)
Cc:        freebsd-hackers@FreeBSD.org
Subject:   Re: handling SIGCHLD with multiple children
Message-ID:  <199607092142.OAA25120@phaeton.artisoft.com>
In-Reply-To: <Pine.BSF.3.91.960709122409.4725A-100000@tombstone.sunrem.com> from "Brandon Gillespie" at Jul 9, 96 12:26:35 pm

next in thread | previous in thread | raw e-mail | index | archive | help
> Is there _ANY_ way of finding what child sent a SIGCHLD signal to the 
> parent process?  I have a situation where a parent may have multiple 
> children processing different tasks, and the parent is waiting for one 
> child to complete a specific task, which it cares about, but it does not 
> care about the other children.  Because of this in most instances when 
> SIGCHLD is received it simply resets it and continues working, except for 
> now I need to handle things differently when a specific child sends 
> SIGCHLD.  Is there any ANY way to figure out where it came from?

Signals are persistent conditions, not events.

A signal handler will block deliver of on signal behind.

It is therefore not a good idea to call wait in the SIGCHLD handler
itself, since it introduces apotential race condition in disposing
the signal.


The correct method would be to program in terms of an event loop; I
don't know the architecture of the parent process, but if it is an
event loop, then you can do the following:

1)	Establish a SIGCHLD signal handler; if a SIGCHLD signal is
	received, then a volatile variable should be set to indicate
	one or more children need to be reaped.

2)	Arrange the main loop as follows:

	a)	check the volatile flag; dispatch to inband handler
		function if set
	b)	set SIGCHLD to interrupt system calls
	c)	call the main loop hang-pending-event call (usually
		select or other system call)
	d)	on handler return, reset interrupt on SIGCHLD do only
		the hang is interruptable.
	d)	check hang-pending-event return value for interrupt
	e)	if interrupted, go to top of main loop

3)	Create an inband handler function for SIGCHLD; this function
	will:

	a)	call wait(2) with WNOHANG option
	b)	on -1, processing is complete (no more PID's to return)
	c)	use the return value to hash-index a list of child
		processes that are outstanding (return value is PID).
	d)	set a flag (does not need to be volatile) to indicate
		that anyone waiting for this process to complete may
		now proceed.


This approach was used successfully in a "X port monitor" to allow
management of logins on up to 32 terminals (highest tested amount;
highest theoretical amount was 256 becase of FD_SETSIZE) using a
single process (instead of running one xdm per X terminal -- a huge
memory waster on a Sun machine).

This approach was also successfully used for a pipe-based linkage
system, similar to that employed by Khoros, to similar effect for
a tools-based image processing "drag-and-drop" workbench.


					Terry Lambert
					terry@lambert.org
---
Any opinions in this posting are my own and not those of my present
or previous employers.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199607092142.OAA25120>