Search code examples
perlloopsfork

Why including a fork() call creates more loops


When I include fork() function call in the loop, the loop executes more than the expected times. For the sake of simplicity, I have chosen only two iterations; you can test with more than that.

I have tried setting the autoflush on but that doesn't seem to work.

use strict;
use warnings;
use IO::Handle;

$|++; #autoflush on
STDOUT->flush();

for my $i (1 .. 2) {
    print "Normal => $i\n";
}
print "\n";

for my $i (1 .. 2) {
    my $pid = fork();
    if(not defined($pid)) {
       die "cannot fork\n";
    } elsif (not $pid) {
       print "Child  => $i\n";
    } else {
       print "Parent => $i\n";
       wait();
    }
}

Actual Output

Normal => 1
Normal => 2

Parent => 1
Child  => 1
Parent => 2
Child  => 2
Parent => 2
Child  => 2

Expected Output

Normal => 1
Normal => 2

Parent => 1
Child  => 1
Parent => 2
Child  => 2

Please help me understanding what is wrong here.


Solution

  • Similar question and answer can be found at https://stackoverflow.com/a/8318556/542995

    Because your code will have the first child to start iterating exactly the same as the parent does.

    So, just to simply, in order to prevent extra loop. You may have to exit the child job and put wait(); for parent in response to finished job in a separate loop. And, that will lead to what you expected.

    use strict;
    use warnings;
    
    my $n = 2;
    
    for my $i (1 .. $n) {
      my $pid = fork;
      if (not $pid) {
        print "Child: $i\n";
        exit;
      } else {
        print "Parent $i\n";
      }
    }
    
    for (1 .. $n) {
       wait();
       print "Job finished\n";
    }
    

    Output:

    Parent 1
    Parent 2
    Child: 1
    Child: 2
    Job finished
    Job finished