Forking in Perl 2

Build up an index of files to process, e.g. SAM files. Fork out 16 child processes, each time processing and eliminating one file from the index. As with all my code, use at your own risk. Comments and suggestions always welcome.

#!/usr/bin/perl

use strict;
use warnings;

my $fork_process = '16';
my @file_for_processing = ();
my @child = ();

opendir(DIR,'.') || die "Could not open current directory: $!\n";
while(my $file = readdir(DIR)){
   next unless $file =~ /\.sam.gz$/;
   push(@file_for_processing,$file);
}
closedir(DIR);

while(scalar(@file_for_processing) > 0){
   for (1 .. $fork_process){
      my $pid = fork();
      if ($pid) {
         # parent
         push(@child, $pid);
         pop(@file_for_processing);
      } elsif ($pid == 0) {
         # child
         if (scalar(@file_for_processing) > 0){
            print "CHILD: processing $file_for_processing[-1]\n";
         }
         exit(0);
      } else {
         die "Couldn't fork: $!\n";
      }
   }
   foreach my $pid (@child) {
      waitpid($pid, 0);
   }
}

exit(0);

For more information see Forking in Perl.

Forking in Perl

Foreach item in the array, start a fork. $pid returns 0 if it is the child process. This way you can spawn 4 child processes from one parent. This page explains it all and the code shown below is an adaptation of code shown from the link. I just added code to show the current process id and the process id of the child.

#!/usr/bin/perl

use strict;
use warnings;

my @seq = qw/one two three four/;

my @childs = ();

warn "Starting on \n: created new fork on $pid\n";
   if ($pid) {
      # parent
      warn "\tPushing $pid into array\n";
      push(@childs, $pid);
   } elsif ($pid == 0) {
      # child
      warn "\tRunning child process for $seq\n";
      exit(0);
   } else {
      die "Couldn't fork: $!\n";
   }
}

foreach my $pid (@childs) {
   waitpid($pid, 0);
}

print "Done\n";