Process Creation and Monitoring

#!/usr/bin/perl 
######  Demonstration of Process Creation, Monitoring, and Destruction  ######

open(LOG,">>logfile") || die "Can't open logfile.\n";

#  Sys_wait_h has waitpid and associated constants.
use POSIX qw(sys_wait_h);   

#  Go to clear_zombie when a child process has finished.  Gets rid of
#  zombie processes so that we do not overflow our quota of processes
#  which would make fork() fail!! 
$SIG{CHLD} = \&clear_zombie;

#  Loop creates 20 processes.
for ($i = 0; $i < 20; $i++)
{
#  Fork a parent process and a child process.  See if it worked.
     $pid = fork();
     die "Fork failed!\n" unless defined($pid);

     if ($pid == 0)   ####### Child process!
     {
    #  Current date/time will be written to the log file.
          chomp($date = localtime);

    #  Processes created when loop variable is even will be timed out!
          sleep(1000) if $i % 2 == 0;

    #  $$ is the process id of the current process.
          printf(LOG "%-30s %ld\n", $date, $$);
          exit(0);   #  Absolutely vital!!!!!!!!!
     }
     else  ######  Parent process!
     {
          $pids{$pid} = 1;   #  Store pids for easy access by $pid key.
          if ($i == 19)      #  Set alarm on last loop iteration.
          {
              $SIG{ALRM} = \&killer;
              alarm 15;
              while(1) {sleep 1000}   #  Keep parent alive for SIGALRM!
                                      #  While loop necessary because sleep
                                      #  is NOT RE-ENTRANT!!
          }
     }
}



sub clear_zombie
{
     my $corpse;

#  -1 parameter to waitpid means "any process in the logon process group".
     while(($corpse = waitpid(-1, WNOHANG)) > 0)
     {
           delete $pids{$corpse};
           print "Cleared $corpse.\n";
     } 
}
sub killer
{
    my $pid;

    print "Goodbye cruel world!\n";

#   Tell user which active processes are going to be killed.
    foreach $pid (sort keys %pids) {print "Process $pid being killed!\n"}

#   Process zero means all processes UNDER the logon process.  We do not
#   want to kill our logon process!!
    kill 'KILL', 0;  #  Zero means anything in this process group.
}
############################  Program Output Below  ##########################

$ process.pl
Cleared 1261.
Cleared 1267.
Cleared 1265.
Cleared 1263.
Cleared 1273.
Cleared 1271.
Cleared 1269.
Cleared 1279.
Cleared 1277.
Cleared 1275.

Goodbye cruel world!
Process 1260 being killed!   #  Dump of hash of active pids.
Process 1262 being killed!
Process 1264 being killed!
Process 1266 being killed!
Process 1268 being killed!
Process 1270 being killed!
Process 1272 being killed!
Process 1274 being killed!
Process 1276 being killed!
Process 1278 being killed!
Killed   #  Message from Unix.

$ cat logfile
Fri Aug 27 16:20:44 1999       1261    #  Time and pid in logfile.
Fri Aug 27 16:20:44 1999       1263
Fri Aug 27 16:20:44 1999       1265
Fri Aug 27 16:20:44 1999       1267
Fri Aug 27 16:20:44 1999       1269
Fri Aug 27 16:20:44 1999       1271
Fri Aug 27 16:20:44 1999       1273
Fri Aug 27 16:20:44 1999       1275
Fri Aug 27 16:20:44 1999       1277
Fri Aug 27 16:20:44 1999       1279
$