UNIX question

daemon at houligan.UUCP daemon at houligan.UUCP
Thu Dec 19 05:20:13 AEST 1985


In <156 at uw-june> pjs at uw-june (Philip J. Schneider) writes:
> I have a C program which, during the course of its execution,
> spawns(forks) child processes. ...  Since UNIX only allows one a
> certain number of processes at a time, eventually during the course of
> execution of the parent I run out of processes.  If I temporarily stop
> the parent process execution and do a 'ps', the child processes show up
> in the list with a 'Z' status.  They do not completely disappear until
> the parent process exits.
>
> My question: Is there any way to kill off these zombies so I can get
> 	     more processes ?  Or, failing that, is there any other
> 	     way to do what I want ?
>
> Philip Schneider                               
> University of Washington Computer Science                
> pjs@{uw-june.arpa,washington.arpa}                      
> {ihnp4,decvax,cornell}!uw-beaver!uw-june!pjs           

The problem (and fortunately, the solution) is simple.  A process, once
terminated, becomes a "zombie" (Z status from "ps") until its parent
(as determined by its PPID) "wait"s for it.  Thus, it is the parent
process' responsibility to "clean up after" its children (kinda like
real life, eh?)

You can do one of two things, depending on your situtation, to handle
this correctly.

1.  If the parent process does not have anything better to do while the
    children are out playing, it can just "wait" for them to finish.

2.  You can cause the parent to "double-fork".  This will make it a
    "grand-parent" for a time, just long enough for the "parent" to
    fork the child, and then terminate (exit).  Then, when the
    "grand-parent" waits for the "parent", it will be VERY quick, and
    should not impact the "grand-parent" (original spawning process)
    much, in terms of slowing down the execution.  Then, the "child"
    will become an "orphan", and when it terminates, the system "init"
    process (PID = 1) will clean up after it.

Implementation of the "double-fork" is simple (error detection omitted for
clarity).

/* grand-parent */	switch (fork()) {
/* parent */		case 0:
/* parent */			switch (fork()) {
/* child */			case 0:
/* child */				/* do the "child" part */
/* child */				break;
/* parent */			default:
/* parent */				exit(0); /* orphan the child */
/* parent */			}
/* grand-parent */	default:
/* grand-parent */		wait(0); /* wait for "parent" */
/* grand-parent */	}
/* grand-parent */	/* proceed with normal processing */

Obviously, the "wait" and "fork" calls need to be checked for errors,
and you may want to use "_exit" instead, in the "parent", so it doesn't
flush <stdio> buffers, etc.  These are left as exercises for the
reader.

--tgi
	while (--tgi)	/* my mind continues to decay */
		;	/* even though I do nothing.. */    

{brl-bmd,ccvaxa,pur-ee,sun}!csd-gould!midas!tgi (Craig Strickland @ Gould)
305/587-2900 x5014  CompuServe: 76545,1007   Source: BDQ615   MCIMail: 272-3350

(echo ".ft B"; echo ".ps 999"; echo "$disclaimer") | troff -t	# :-)



More information about the Comp.unix mailing list