DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

Run A Function On List Of Arguments Parallely With Fork

11.05.2008
| 2092 views |
  • submit to reddit
        // This code itarate through all the elements of an array @list_of_argument_for_fake and pass each element as argument to function called &fake(). This one cycler foks 5 children at a time and execute &fake() in each child.

// Code snippet for process stack

#!/home/y/bin/perl -w

use strict;
use POSIX;

use constant STACK_OF     => 5;
use constant FORK_ATTEMPT => 5;

my $INTRRUPT    = 0;
my $FORK_FAILED = 0;

my @list_of_argument_for_fake =
  qw( one two three four five six seven eight nine ten   );

local $SIG{ALRM} = $SIG{INT} = $SIG{TERM} = \&action_sig;

&ProcessStack( \@list_of_argument_for_fake, \&fake );

sub ProcessStack {
    my $arguments = shift;
    my $action    = shift;
    my $STACK     = {};

  PROCESS_STACK_START:
    while ( ( ( scalar(@$arguments) ) > 0 ) && ( $INTRRUPT == 0 ) ) {
        my ( $arg, $child );
        if ( ( STACK_OF - 1 >= scalar( keys %$STACK ) ) && ( $INTRRUPT == 0 ) )
        {
            unless ( defined( $child = fork() ) ) {
                die "Couldnt fork: $!";
                if ( ++$FORK_FAILED > FORK_ATTEMPT ) {
                    die "No more forking, getting out of while loop";
                }
                next;
            }
            $arg = shift @$arguments;
            $STACK->{$child} = $arg;
        }
        else { sleep(1); $STACK = &sig_chld($STACK); next; }

        if ( $child == 0 ) {
            $action->($arg);
            exit;
        }
        else { sleep(1); $STACK = &sig_chld($STACK); }
    }
    while ( ( keys %$STACK ) > 0 ) { sleep(1); $STACK = &sig_chld($STACK); }
}

sub action_sig {
    local $SIG{ALRM} = $SIG{INT} = $SIG{TERM} = \&action_sig;
    $INTRRUPT = 1;
}

sub sig_chld {
    my $STACK = shift;
    my $c;
    if ( ( $c = waitpid( -1, WNOHANG ) ) > 0 ) { delete $STACK->{$c}; }
    return $STACK;
}

sub fake {
    my $arg    = shift;
    my $number = 30;

    print "$arg\n";
    sleep $number;
}