[comp.unix.wizards] forking and zombies in SYSV.

jh@efd.lth.se (Joergen Haegg) (08/20/90)

A question about how to fork() in SYSV.

I want to fork, and the parentprocess should continue without
doing a wait().
When the child exits, it is transformed into a zombieprocess.
The zombie exists until the parent exits.
This is as it should be according to SVID.

How do I avoid getting this zombie?

The only way, am I told, is to let the child fork again and exit.
The parent will wait() for the first child, but not the child of 
the first child.

The second child will not create a zombie, because the parent 
(the first child) is dead.
This seems a bit silly, because /etc/init forks all the time and without
any zombies. (Ok, init is maybe a little special :-)

Is there not a cleaner way to do this?

-- 
--
Joergen Haegg				jh@efd.lth.se	postmaster@efd.lth.se
System manager @ efd			046-107492
Lund Institute of Technology		Sweden

thomas@uplog.se (Thomas Tornblom) (08/20/90)

In article <1990Aug20.133107.12516@lth.se> jh@efd.lth.se (Joergen Haegg) writes:

   A question about how to fork() in SYSV.

   I want to fork, and the parentprocess should continue without
   doing a wait().
   When the child exits, it is transformed into a zombieprocess.
   The zombie exists until the parent exits.
   This is as it should be according to SVID.

   How do I avoid getting this zombie?

   The only way, am I told, is to let the child fork again and exit.
   The parent will wait() for the first child, but not the child of 
   the first child.

   The second child will not create a zombie, because the parent 
   (the first child) is dead.
   This seems a bit silly, because /etc/init forks all the time and without
   any zombies. (Ok, init is maybe a little special :-)

   Is there not a cleaner way to do this?

   -- 
   --
   Joergen Haegg				jh@efd.lth.se	postmaster@efd.lth.se
   System manager @ efd			046-107492
   Lund Institute of Technology		Sweden

In the parent do a:

signal(SIGCLD, SIG_IGN);

this prevents the creation of a zombie without having to do anything 
in the child.

Thomas
-- 
Real life:	Thomas Tornblom		Email:	thomas@uplog.se
Snail mail:	TeleLOGIC Uppsala AB		Phone:	+46 18 189406
		Box 1218			Fax:	+46 18 132039
		S - 751 42 Uppsala, Sweden

gwyn@smoke.BRL.MIL (Doug Gwyn) (08/21/90)

In article <1990Aug20.133107.12516@lth.se> jh@efd.lth.se (Joergen Haegg) writes:
-How do I avoid getting this zombie?
-The only way, am I told, is to let the child fork again and exit.
-The parent will wait() for the first child, but not the child of 
-the first child.
-The second child will not create a zombie, because the parent 
-(the first child) is dead.
-This seems a bit silly, because /etc/init forks all the time and without
-any zombies. (Ok, init is maybe a little special :-)
-Is there not a cleaner way to do this?

No, and your comment about init is more than a bit silly.
init spends most of its time wait()ing for children,
both its own children and orphaned zombies.

dstailey@gnu.ai.mit.edu (Doug Stailey) (08/21/90)

In article <1990Aug20.133107.12516@lth.se> jh@efd.lth.se (Joergen Haegg) writes:
>A question about how to fork() in SYSV.
>
>I want to fork, and the parentprocess should continue without
>doing a wait().
>When the child exits, it is transformed into a zombieprocess.
>The zombie exists until the parent exits.
>This is as it should be according to SVID.
>
>How do I avoid getting this zombie?
>
Try signal(SIGCHLD, SIG_IGN) to avoid generating zombies.

bbausch@hpbbi4.BBN.HP.COM (#Bernd Bausch) (08/21/90)

> 
> I want to fork, and the parentprocess should continue without
> doing a wait().
> When the child exits, it is transformed into a zombieprocess.
> The zombie exists until the parent exits.
> This is as it should be according to SVID.
> 

Under HP-UX, you can ignore or catch the SIGCLD signal. That's documented
in signal(5).

---
Bernd Bausch
Hewlett-Packard Boeblingen
Germany

rml@hpfcdc.HP.COM (Bob Lenk) (08/24/90)

Several people have suggested

	signal(SIGCLD, SIG_IGN);

While this does prevent zombies from being formed in System III, System
V, and compatible systems, there are some reasons to avoid it:

	1) Portability.  This does not work in all implementations
	   (notably not in BSD).  It is not required by POSIX, XPG,
	   or even the SVID.  

	2) Possible side-effects.  This can impact any part of your
	   program that creates children, including library calls that
	   might create children for reasons unknown to you.  It can
	   impact the programs exec'd by descendents if they create
	   children.  Most code that creates children expects to wait
	   for them.  This can cause such code to hang (until all your
	   children have died) and/or to get unexpected errors (possibly
	   missing out on important status information).

It is generally worth waiting for child processes in some way.

		Bob Lenk
		rml@fc.hp.com
		{uunet,hplabs}!fc.hp.com!rml

lfd@cbnewsm.att.com (leland.f.derbenwick) (08/28/90)

In article <5980067@hpfcdc.HP.COM>, rml@hpfcdc.HP.COM (Bob Lenk) writes:
> Several people have suggested
> 
> 	signal(SIGCLD, SIG_IGN);
> 
> While this does prevent zombies from being formed in System III, System
> V, and compatible systems, there are some reasons to avoid it:
> 
> 	1) Portability.  This does not work in all implementations
> 	   (notably not in BSD).  It is not required by POSIX, XPG,
> 	   or even the SVID.  

This behavior _is_ required by the SVID: see "signal(BA_OS)" on
page 6-124 of Volume 1 of the Third Edition (8/89):

   If the diposition for SIGCHLD is set to SIG_IGN, the calling
   process's child processes will not create zombie processes
   when they terminate [see exit(BA_OS)].  If the calling process
   subsequently waits for its children, it will block until all
   of its children terminate; it will then return a value of -1
   with errno set to ECHILD ...

> 	2) Possible side-effects.  This can impact any part of your
> 	   program that creates children, including library calls that
> 	   might create children for reasons unknown to you.  It can
> 	   impact the programs exec'd by descendents if they create
> 	   children.  Most code that creates children expects to wait
> 	   for them.  This can cause such code to hang (until all your
> 	   children have died) and/or to get unexpected errors (possibly
> 	   missing out on important status information).

This is correct, but it would be simple to add

   signal(SIGCHLD, SIG_DFL);

to the child processes (in main() if they are invoked via "system",
or just after the fork() if the fork()/exec() is done explicitly).

 -- Speaking strictly for myself,
 --   Lee Derbenwick, AT&T Bell Laboratories, Warren, NJ
 --   lfd@cbnewsm.ATT.COM  or  <wherever>!att!cbnewsm!lfd

guy@auspex.auspex.com (Guy Harris) (08/30/90)

 >This behavior _is_ required by the SVID: see "signal(BA_OS)" on
 >page 6-124 of Volume 1 of the Third Edition (8/89):

Yes, but it's not required by Issue 2 of the SVID.