Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: $Revision: 1.6.2.16 $; site ima.UUCP Path: utzoo!watmath!clyde!burl!ulysses!allegra!mit-eddie!genrad!panda!talcott!harvard!bbnccv!ima!johnl From: johnl@ima.UUCP Newsgroups: net.unix Subject: Re: UNIX question Message-ID: <125800001@ima.UUCP> Date: Sat, 7-Dec-85 21:21:00 EST Article-I.D.: ima.125800001 Posted: Sat Dec 7 21:21:00 1985 Date-Received: Mon, 9-Dec-85 03:25:55 EST References: <156@uw-june>.UUCP> Lines: 49 Nf-ID: #R:uw-june>:-15600:ima:125800001:000:2155 Nf-From: ima!johnl Dec 7 21:21:00 1985 /* Written 7:38 pm Dec 5, 1985 by pjs@uw-june> in ima:net.unix */ > I have a C program which, during the course of its execution, spawns(forks) > child processes. I should mention that a process is spawned, it lives > for a while, then exits, and then sometime later the same thing happens, > and so on. This all happens within the lifetime of the parent, and I > would like to do this an arbitrary number of times. Sometimes, two or > more child processes exist at once, but the upper limit on child > processes that exist concurrently is low, and a group of such children > exit before the next process begins. > > 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. The problem here is a minor misunderstanding of how fork() and wait() interact. Each time a process dies, it has some status to return to its parent when the parent wait()s for it. A zombie process is one that has died but whose parent hasn't yet waited for it, so the way to get rid of zombies is to make sure that somebody collects them with a wait(). If you know at some point that all of your subprocesses have died, you can just wait for all of them by calling wait() until it returns -1 with error code ECHILD, then go ahead and spawn any more children. The other possibility is to take advantage of the fact that when a process' parent dies, the orphan is handed to init, the top level process. Use code like this (real code should have error checking, but you get the idea): ... pid = fork(); if(pid != 0) while(wait(0) != pid) /* parent here waits for child */ ; else { /* child */ if(fork() != 0) exit(0); /* child exits right away */ /* grandchild here is inherited by init, can go off and */ /* do what it wants */ } Init spends most of its time in a wait() loop and can be counted on to collect the orphaned grahdchild when it exits. The child is collected promptly by the wait call in the parent, so there will be no zombie problem. Pedantically, John Levine, ima!johnl PS: This is all in the manual, but perhaps not so crystal clear.