lhp@nereida:~/Lperl/src/perl_networking/ch2$ cat -n facfib.pl 1 #!/usr/bin/perl -w 2 use strict; 3 use IO::Handle; 4 5 my $arg = shift || 10; 6 7 my ($READER, $WRITER) = (IO::Handle->new, IO::Handle->new); 8 pipe($READER, $WRITER) or die "Can't open pipe: $!\n"; 9 10 if (fork == 0) { # first child writes to $WRITER 11 close $READER; 12 $WRITER->autoflush(1); 13 factorial($arg); 14 exit 0; 15 } 16 17 if (fork == 0) { # second child writes to $WRITER 18 close $READER; 19 $WRITER->autoflush(1); 20 my $result = fibonacci($arg); 21 exit 0; 22 } 23 24 # parent process closes $WRITER and reads from $READER 25 close $WRITER; 26 print while <$READER>; 27 do {} while wait > 0; 28 29 sub factorial { 30 my $target = shift; 31 for (my $result = 1,my $i = 1; $i <= $target; $i++) { 32 syswrite $WRITER, "factorial($i) => ".($result *= $i)."\n"; 33 } 34 } 35 36 sub fibonacci { 37 my $target = shift; 38 for (my $result = 1,my $i = 1; $i <= $target; $i++) { 39 syswrite $WRITER, "fibonacci($i) => ".($result += $i)."\n"; 40 } 41 }La función
pipe
permite al proceso padre
escuchar a todos los procesos hijo en el mismo canal
READER
. Después del fork
el lector
cierra la parte WRITER
y el escritor
la parte READER
. Si no se hiciera así
el EOF
causado por el cierre del WRITER
no llegaría al READER
.
Es también importante asegurarse que el escritor
está en modo autoflush .
Al ejecutar se entrelazan las salidas:
lhp@nereida:~/Lperl/src/perl_networking/ch2$ ./facfib.pl 18 fibonacci(1) => 2 fibonacci(2) => 4 factorial(1) => 1 fibonacci(3) => 7 fibonacci(4) => 11 factorial(2) => 2 fibonacci(5) => 16 factorial(3) => 6 fibonacci(6) => 22 factorial(4) => 24 fibonacci(7) => 29 factorial(5) => 120 fibonacci(8) => 37 factorial(6) => 720 fibonacci(9) => 46 factorial(7) => 5040 fibonacci(10) => 56 factorial(8) => 40320 fibonacci(11) => 67 factorial(9) => 362880 fibonacci(12) => 79 factorial(10) => 3628800 fibonacci(13) => 92 factorial(11) => 39916800 fibonacci(14) => 106 factorial(12) => 479001600 fibonacci(15) => 121 fibonacci(16) => 137 fibonacci(17) => 154 fibonacci(18) => 172 factorial(13) => 6227020800 factorial(14) => 87178291200 factorial(15) => 1307674368000 factorial(16) => 20922789888000 factorial(17) => 355687428096000 factorial(18) => 6.402373705728e+15 lhp@nereida:~/Lperl/src/perl_networking/ch2$A la vista del funcionamiento del ejemplo resulta lógico suponer que el acceso al canal por los hijos/escritores ocurre en exclusión mutua.
Casiano Rodríguez León