home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/ActivePerl-5.6/bin/perl -w
- #
- # forker.pl
- #
- # This script is a simple demonstration of how to use fork()
- #
- # Author: David Sparks <dave@ActiveState.com>
-
- use strict;
- use warnings;
-
- use constant CLIENTS => 32;
- use constant DEBUG => 1;
- $|=1; #buffering a bad idea when fork()ing
-
- my @kids=();
- my $pid=$$;
- my $parentpid=0;
-
-
- #script starts here
- SharedInit();
-
- Forker(CLIENTS);
-
- if ($parentpid) {
- Work();
- }
- else { #the original parent only does cleanup duty
- Reaper();
- }
-
- warn "$$ exiting\n" if DEBUG;
-
- if ($parentpid) {
- #kids exit here
- exit(0);
- }
- else {
- #parent exits here
- exit(0);
- }
- die; #wont happen
-
-
- sub Forker {
- my $clients=shift;
- my $i=0;
- while ($i++ < $clients) {
- my $newpid = fork();
- if (! defined $newpid) { #hosed
- die "fork() error: $!\n";
- }
- elsif ($newpid == 0) { #child
- $parentpid = $pid;
- $pid = $$;
- @kids = (); #don't inhert the kids
- warn "$$ child of $parentpid\n" if DEBUG;
- last;
- }
- else { #parent (defined $newpid)
- warn "$$ spawned $newpid\n" if DEBUG;
- push(@kids, $newpid);
- }
- }
- }
-
- sub SharedInit {
- warn "Entering SharedInit()\n" if DEBUG;
-
-
- }
-
- sub Work {
- warn "$$ Entering Work()\n" if DEBUG;
-
-
- }
-
- sub Reaper {
- while (my $kid = shift(@kids)) {
- warn "$$ to reap $kid\n" if DEBUG;
- my $reaped = waitpid($kid,0);
- unless ($reaped == $kid) {
- warn "waitpid $reaped: $?\n" if DEBUG;
- }
- }
- }
-
- __END__
-
- use POSIX ":sys_wait_h";
- do {
- $kid = waitpid(-1,&WNOHANG);
- } until $kid == -1;
-
-