jeremy_goodrich has asked for the wisdom of the Perl Monks concerning the following question:

Following is my first attempt at forking a child process in a perl script. The purpose of the following is to read in a text file, process remove requests from a mailing list, and then print out a file which has been cleaned. (so that people who don't want to get emails don't get them). As you can see, I'm using -w and strict, this script does work (the openDatabase and closeDatabase routines are missing, but those work fine). The current output of this script is about 2.5 times the size of the original script, because it is looping over the sets of 5000 to process at the same time. I've checked, and everything seems to go right, except for the duplicate times that I believe the child processes are running...any help figuring out what to do to make each only loop over their set to process and then die would be greatly appreciated.
#!/usr/bin/perl -w $|++; use strict; use DBI; my $testdata = "test.txt"; my %datahash = (); my $c = "1"; my $x = "1"; my $i = 0; my @points; my @removeEmails = ''; my $timetowrite = ''; my $key = ''; my $value = ''; my $dbh = ''; my $exquery = ''; my $removeData = ''; my $removeEmail = ''; my $batch = ''; my @emailsText = ''; my @cleanEmails = ''; my @removeList = ''; my @inFile; my %test = (); my $crap = ''; my $email = ''; my $blank = ''; my $loops = shift || 10; my @dataset = ''; my $totalin = ''; my $pid = ''; my $ending = ''; my $r = ''; my $remove = ''; my $b = 0; print "Testing with $loops children...\n"; open ( CLEAN, ">>aclean\.txt" ) || die " clean\.txt $! \n "; open (ADDRESS, $testdata); @dataset = (<ADDRESS>); close ADDRESS; $totalin = scalar @dataset; &openDatabase; shift (@points); for ($i=0;$i<$loops;$i++) { if ($pid = fork) { next; } ## Parent gets the credit... if (defined $pid and $ending !~ "true") { ## ...children do the work # this is where the 500 at a time processing goes $| = 1; $i++; $timetowrite = ($i * 5000); # die "timetowrite $timetowrite\n"; $c = ($timetowrite - 4999); if ($totalin > $c) { @emailsText = &openText($testdata, $timetowrite, $c); foreach my $address (@emailsText) { $" = "|"; chomp $address; $address =~ s/\r|\n|\s//gi; $b++; # Ok - current address is valid - lets + see if its on the remove list. # print "This Address: $address\n"; $remove = 0; my $exquery = $dbh->prepare(qq{SELECT * from m +lm_remove WHERE email='$address'}); $exquery->execute(); while (my $removeData = $exquery->fetchrow_has +href()) { my $removeEmail = $removeData->{email} +; if($removeEmail eq $address) { print "$b -**->$address failed + -- INTERNAL REMOVE LIST\n"; $r++; $remove = 1; } } if ($remove < 1) { select CLEAN; printf <CLEAN>,"$address\n"; select STDOUT; } } exit; } else { $ending = "true"; exit; } } else { ## Uh-oh something is really wrong ## The parent is saying this... die "Fork failed at number $i: $!\n"; } } &closeDatabase; exit; 1; sub openText { ($testdata,$timetowrite,$c) = (@_); # die "$testdata $timetowrite $c\n"; my @emailsText; open STUFF, "$testdata" or die "noop"; foreach (<STUFF>) { ($key, $value)= split (/ /, $_); chomp $_; if ($c <= $key ) { push @emailsText, $value; # print "added $value to the array\n"; } if ($timetowrite == $key) { close (STUFF); return @emailsText; } } close (STUFF); return @emailsText; }