Q: How to eliminate leftover <defunct> processes from child 
Author Message
 Q: How to eliminate leftover <defunct> processes from child

Is it possible to avoid having leftover <defunct> processes after a
child process quits?  I am playing around with the sample daemon code
provided in the perl 4.036 man pages, and modified it to run a couple
of processes via open(FILEHANDLE, "process |") and pipe the output
back to the client.  I made sure that all handles are closed when done.

Although the extra processes do not consume CPU time, I don't want
them{*filter*} around until the parent quits, seeing that in the case of
a daemon, the parent never quits..

Thanks
Steve
--
Stephen Hsieh              Dept. of Electrical Engineering and Computer Science

-------------------------------------------------------------------------------



Sat, 15 Mar 1997 01:12:45 GMT  
 Q: How to eliminate leftover <defunct> processes from child

Quote:
>Yes.  Interpolate a process whose only purpose is to spawn the child
>(actually a grandchild now) and which exits immediately.

In the original post he said he was creating the child process with
open(FILEHANDLE, "command |");.  If he interposes a process, the original
process won't have FILEHANDLE, so it won't be able to read the output of
the process.

I don't understand why Perl is leaving a zombie in this case.  He said that
he closes FILEHANDLE after reading all the output.  Closing a pipe has to
call wait(2) so that it can get a value to put in $?, and calling wait(2)
is how you get rid of zombies.
--

Barry Margolin
BBN Internet Services Corp.



Sun, 16 Mar 1997 00:36:02 GMT  
 Q: How to eliminate leftover <defunct> processes from child


Quote:

>Is it possible to avoid having leftover <defunct> processes after a
>child process quits?  I am playing around with the sample daemon code

[...]

Yes.  Interpolate a process whose only purpose is to spawn the child
(actually a grandchild now) and which exits immediately.  The parent
process can wait() for the intermediate one, because it ends quickly
so this one doesn't become a zombie.  The grandchild is inherited by
the init process, which wait()s for it as soon as it exits, so that one
won't leave a defunct process either.  This trick isn't specific to
perl but is used routinely in a unix system.

Anno



Sat, 15 Mar 1997 16:54:30 GMT  
 Q: How to eliminate leftover <defunct> processes from child

Quote:


>>Yes.  Interpolate a process whose only purpose is to spawn the child
>>(actually a grandchild now) and which exits immediately.

>In the original post he said he was creating the child process with
>open(FILEHANDLE, "command |");.  If he interposes a process, the original
>process won't have FILEHANDLE, so it won't be able to read the output of
>the process.

Right.  I should make a habit of reading a posting before a followup.

Quote:
>I don't understand why Perl is leaving a zombie in this case.  He said that
>he closes FILEHANDLE after reading all the output.  Closing a pipe has to
>call wait(2) so that it can get a value to put in $?, and calling wait(2)
>is how you get rid of zombies.

Right again.

Anno



Mon, 17 Mar 1997 02:44:09 GMT  
 Q: How to eliminate leftover <defunct> processes from child

Quote:


>...

>Date: Tue, 27 Sep 94 10:54:31 +0100


>Those examples don't take care of SIGCHLD. You must set up a signal
>handler for it, and beware, "$SIG{'CHLD'} = 'IGNORE'" doesn't
>work, at least not on my systems. I use the following prototypical
>server loop:
>...  omitted for brevity
>in what the child does, it would simply ignore SIGCHLD, but alas,
>-------------------------------------------------------------------------------

Actually, $Sig{'CHLD'} = 'IGNORE' works on AIX 3.2+ (SysV-ish).

--

Boeing Computer Services                UUCP:       ...!uunet!bcstec!ced



Mon, 17 Mar 1997 04:22:10 GMT  
 Q: How to eliminate leftover <defunct> processes from child
...
BM> I don't understand why Perl is leaving a zombie in this case.  He
BM> said that he closes FILEHANDLE after reading all the output.
BM> Closing a pipe has to call wait(2) so that it can get a value to
BM> put in $?, and calling wait(2) is how you get rid of zombies.  --

Thanks to Andreas Karrer who answered with the following. The model he
provided works for my situation:


Date: Tue, 27 Sep 94 10:54:31 +0100


Newsgroups: comp.lang.perl
Subject: Re: Q: How to eliminate leftover <defunct> processes from child

In comp.lang.perl you write:

Quote:
>Is it possible to avoid having leftover <defunct> processes after a
>child process quits?  I am playing around with the sample daemon code
>provided in the perl 4.036 man pages,

Those examples don't take care of SIGCHLD. You must set up a signal
handler for it, and beware, "$SIG{'CHLD'} = 'IGNORE'" doesn't
work, at least not on my systems. I use the following prototypical
server loop:

$EINTR = 4; # Interrupted system call, from <sys/errno.h> or so

socket(SOCK, $PF_INET, $SOCK_STREAM, $proto)    || die("socket: $!");
bind(SOCK, $wksock)                             || die("bind: $!");
listen(SOCK, 5)                                 || die("listen: $!");

select(SOCK);    $| = 1;
select(NEWSOCK); $| = 1;

$SIG{'CHLD'} = 'reaper';
sub reaper { while (wait != -1) { } }

while (1) {
    # accept is one of the system calls that does not restart itself when
    # a signal -- in this case SIGCHLD -- is recevied
    do {
        close(NEWSOCK);
        $! = 0;
        $NSaddr = accept(NEWSOCK, SOCK);
    } while ($! == $EINTR);
    if ($!) { die "accept: $!"; }

    if (fork() == 0) {
        close(SOCK);
        # do kid stuff, like reading from <NEWSOCK> and processing requests
        $request = <NEWSOCK>;
        &do_the_work($request);
        shutdown(NEWSOCK, 2);
        exit 0;
    } else {
        # do stuff parents like to do; often nothing
    }

Quote:
}  


Date: Wed, 28 Sep 94 09:39:29 +0100


Subject: Re: Q: How to eliminate leftover <defunct> processes from child

Quote:
>Thanks for your reply.  I'll give it a try.  What signal is SIGCHLD? I'm
>not exactly clear why I need it, because the child process quits on its
>own, and is not killed by the parent. (ie: child ends with an exit)

SIGCHLD is the signal a child sends to its parent when it is about to
exit. If the parent does not wait for SIGCHLD, the child becomes a
zombie (bowlderized versions of Unix use the euphemism "defunct
process"). Ideally, if the server process is not really interested
in what the child does, it would simply ignore SIGCHLD, but alas,
$SIG{'CHLD'} = 'IGNORE' doesn't work in perl 4.036.

If the parent process terminates before the child, init inherits the
child (becomes the child's "grandparent", or the parent of all
"orphaned" processes. The comparison to human family relationships gets
boring quickly...). init awaits all SIGCHLD signals and ignores them
(apart from collecting accounting information).  This is the technique
used in another reply to your posting.

+-----------
  Andi Karrer, Institute for Electronics, ETH Zuerich, Switzerland

  - CH stands for Calvin & Hobbs, the most influential Swiss religion

--
Stephen Hsieh              Dept. of Electrical Engineering and Computer Science

-------------------------------------------------------------------------------



Mon, 17 Mar 1997 01:18:55 GMT  
 Q: How to eliminate leftover <defunct> processes from child

Quote:


>>Is it possible to avoid having leftover <defunct> processes after a
>>child process quits?  I am playing around with the sample daemon code

>[...]

>Yes.  Interpolate a process whose only purpose is to spawn the child
>(actually a grandchild now) and which exits immediately.  The parent
>process can wait() for the intermediate one, because it ends quickly
>so this one doesn't become a zombie.  The grandchild is inherited by
>the init process, which wait()s for it as soon as it exits, so that one
>won't leave a defunct process either.  This trick isn't specific to
>perl but is used routinely in a unix system.

>Anno

Or as was pointed out to me use the following to eliminate the cause of defuncts:

select (S); $| = 1; select (stdout);

###  Here is the code that is important - this is not in the Perl books!

$EINTR = &EINTR;

for ($con=1;;$con++) {
  do {
    close (NS);
    $!=0;
    $addr = accept(NS, S);
  } while ($! == $EINTR);

### Now no defunct process!

  if (($child = fork()) == 0) {

---

John C. Wingenbach                 Martin Marietta Energy Systems
                                   Data Systems Research & Development

(615) 574-8345                     1099 Commerce Park
(615) 574-0792 (FAX)               Oak Ridge, TN  37830



Tue, 18 Mar 1997 07:31:07 GMT  
 
 [ 9 post ] 

 Relevant Pages 

1. Killed Process becomes [sh <defunct>]]

2. <defunct> processes

3. Q: <Defunct> processes on HPUX 10

4. <defunct> processes when fork()

5. Child processes don't clean up (defunct processes left) even though SIGCHLD does wait()

6. server.pl and defunct child processes

7. <<<<<< HELP >>>>>>>>

8. fork spawn zombie child process i.e. <defunct> under Solaris

9. `hostname` leaves <defunct>

10. fork spawn zombie child process i.e. <defunct> under Solaris

11. >>>> A Singaporean Girl looking for more penpals!!<<<<<

 

 
Powered by phpBB® Forum Software