I have an array with 5 elements. With each fork, I want the next element to pass to it and then exit. Here's what I've got so far. Could someone please help? :)

Here's what I get:

child 0 k: test1
child 0 k: test2
child 0 k: test3
child 0 k: test4
child 0 k: test5
child 1 k: test1
child 1 k: test2
child 1 k: test3
child 1 k: test4
child 1 k: test5
child 2 k: test1
child 2 k: test2
child 2 k: test3
child 2 k: test4
child 2 k: test5
child 3 k: test1
child 3 k: test2
child 3 k: test3
child 3 k: test4
child 3 k: test5
child 4 k: test1
child 4 k: test2
child 4 k: test3
child 4 k: test4
child 4 k: test5

Here's what I'd like it to say:

child 0 k: test1
child 1 k: test2
child 2 k: test3
child 3 k: test4
child 4 k: test5


Thanks in advance!

code:

#!/usr/bin/perl

@array = qw(test1 test2 test3 test4 test5);

$x=0;
$num = 5;

for ( 1 .. $num ) {
    my $pid = fork();
    if ($pid) {
        push( @childs, $pid );
    }
    elsif ( $pid == 0 ) {
        print "parent\n";
        sleep 5;
        exit(0);
    }
    else {
        die "couldnt fork: $!\n";
    }
}
foreach (@childs) {
        foreach $k (@array) {
                print "child $x k: $k\n";
                next;
        }
                $x++;
}

I haven't used fork and don't know much about it, but doesn't a return value of 0 mean this is a child process? So why does your script print "parent\n"; when the $pid == 0?

How about using an environmental variable to pass each array element to a child, so each child prints one of the elements?

#!/usr/bin/perl
use strict;
use warnings;

my @array = qw(test1 test2 test3 test4 test5);
my $x = 0;

foreach(@array){
    $ENV{X} = $x;
    $ENV{K} = $_;
    my $pid = fork();
    if ($pid) {
        # parent
        waitpid($pid,0);
    } elsif ($pid == 0) {
        # child
        print "child $ENV{X} k: $ENV{K}\n";
        exit(0);
    } else {
        die "couldn’t fork: $!\n";
    }
    $x++;
}

After posting the above, I realised that the trick of writing and reading environment variables served no purpose. The child process can read values of lexical variables set in the parent just as well as it can read environment variables.

I like the following example better. It has five child processes sleeping for five seconds each. Doing five five second tasks sequentially would take 25 seconds altogether but by using fork, the total job takes just five seconds. I guess that's the point of using fork.

#!/usr/bin/perl
use strict;
use warnings;

my @array = qw(test1 test2 test3 test4 test5);
my %children;
my $start = time();

foreach(@array){
    my $pid = fork();
    if ($pid) {
        # parent
        $children{$pid} = $_;#Parent stores children's process ids and one element
    } elsif ($pid == 0) {
        # child
        sleep(5);#Do something that takes 5 seconds
        exit(0);
    } else {
        die "couldn’t fork: $!\n";
    }
}
#wait for all children to finish
for my $pid (keys %children) {
    print "child $pid k: $children{$pid}\n";
    waitpid $pid, 0;
}

my $elapsed = time() - $start;
print "Time elapsed was $elapsed seconds.\n"

Edited 5 Years Ago by d5e5: Removed unneeded variable

This article has been dead for over six months. Start a new discussion instead.