[ale] Any Perl Gurus Out There?

Johnny Preyer JPreyer at sprich.com
Thu Feb 24 11:13:25 EST 2005


Hi all,

As a sidebar, maybe this is the perfect time to mention the attempted
revival of the Atlanta Perl Mongers.  See http://atlanta.pm.org for details;
we've had 2 very good meetings this year, please feel free to visit the web
site, subscribe to the atlanta-pm mailing list, and direct any Perl
questions there.  And, of course, join us at the next meeting!  :)

In addition, I forwarded the question to the atlanta-pm list, here's a
response from Stephen  Adkins, the driving force behind the Atlanta-pm
revival.

- johnny



BACKGROUND:

In a POSIX system (i.e. Unix), a fork() call produces a child
process of the current process.  When the child process dies,
its exit value (a value from 0 to 255) is stored in the process
table.

The process is gone.  All of the memory resources are
reclaimed by the operating system.  The only thing that is 
left of the process is its exit status in the process table.
This is known as a zombie process (or a "defunct" process).
The reason it is kept around is so that the parent process
can find out if it exited normally (an exit status of 0).

There are only two ways to get rid of zombie processes:
   1. the parent process issues one of the wait() family of
      system calls. [wait(), waitpid(), wait2(), wait3(), wait4()]
      This returns the exit status information and clears
      the entry out of the process table.  This is called
      "reaping the exit value of the process".
   2. The parent process exits.  Thus, the child zombie
      processes are inherited by the "init" process (process
      id #1).  The init process is always doing one of the 
      wait() system calls, and it cleans up (reaps) the zombies.

In addition to the exit status, if the process was killed by
a signal, that signal number is also stored in the process
table.

PERL CODE:

#!/usr/bin/perl -w
use strict;
use POSIX ":sys_wait_h";

while (1) {   # infinite loop
    #if (some condition is true) {
    #    do something which forks child processes
    #}
    sleep(60);  # wait for a while
    &clean_up_finished_processes();
}

sub clean_up_finished_processes {
    my ($pid, $exitval, $sig);
    # waitpid(-1,WNOHANG) will check for any child process which
    # has exited (terminated). It will return the process id if
    # if found one or 0 if it did not.
    # The while() loop reaps all of them that have been completed.
    while (($pid = waitpid(-1,WNOHANG)) > 0) {
        $exitval = $? >> 8;
        $sig     = $? & 255;
        # perhaps we want to do something with the results
        print "Child $pid finished [exitval=$exitval,sig=$sig]\n";
    }
}


> -----Original Message-----
> From: Jonathan Glass [mailto:jonathan.glass at oit.gatech.edu]
> Sent: Thursday, February 24, 2005 6:43 AM
> To: ale at ale.org
> Subject: [ale] Any Perl Gurus Out There?
> 
> 
> I've written a little Perl script to monitor a log file and alert (in 
> this case, insert the flagged data into a DB) on a certain 
> pattern.  The 
> parent process sits in an infinite loop watching the file, 
> and whenever 
> the pattern is matched, a child process is forked to do the DB 
> insertion.  Anyone know the proper way to handle the death of 
> all these 
> child processes?  If I run a 'ps -aef' on the box while the script is 
> running, I see dozens of '<defunct>' processes.
> 
> TIA
> 
> Jonathan Glass
> _______________________________________________
> Ale mailing list
> Ale at ale.org
> http://www.ale.org/mailman/listinfo/ale
> 



More information about the Ale mailing list