Un pipe con $ N$ etapas

El ejemplo anterior puede generalizarse a un número arbitrario de etapas. En este ejemplo el proceso padre crea sucesivamente hijos mediante open(STDOUT, "|-") reconectando su STDOUT al STDIN del último hijo creado. Como el hijo hereda el STDOUT del padre en su estado previo a la redirección, tenemos que,

lhp@nereida:~/Lperl/src/cookbook/ch16$ cat -n pipes.pl
 1  #!/usr/bin/perl -w
 2  $| = 1;
 3  use strict;
 4  my $NP = shift || 4;
 5  my $LAST = $NP-1;
 6  my @pid;
 7  $| = 1;
 8
 9  $pid[0] = $$;
10  create_child($NP-$_) for 1..$LAST;
11
12  task(0);
13
14  wait for 1..$LAST;
15  exit;
16
17  sub create_child {
18    my $id = shift;
19
20    return if $pid[$id] = open(STDOUT, "|-");
21    die "Cannot fork $!" unless defined $pid[$id];
22
23    task($id); # do something
24
25    exit;
26  }
27
28  sub task {
29    my $id = shift;
30
31    my $num = $id? <STDIN> : 0;
32
33    $num += $id;
34    $num .= "\n"; # flush
35
36    syswrite STDOUT, $num;
37  }
Al ejecutar tenemos:
lhp@nereida:~/Lperl/src/cookbook/ch16$ pipes.pl 8
28
lhp@nereida:~/Lperl/src/cookbook/ch16$ pipes.pl 7
21
lhp@nereida:~/Lperl/src/cookbook/ch16$ pipes.pl 6
15
lhp@nereida:~/Lperl/src/cookbook/ch16$ pipes.pl 5
10

Casiano Rodríguez León
2012-02-29