Comunicación Bidireccional con Open2

La función open2 del modulo IPC::Open2 provee de canales de lectura-escritura en ambos extremos.

Aqui tenemos un ejemplo de uso de open2. Para llamar a open2 le pasamos referencias a typeglobs o bien objetos IO::Handle

use IPC::Open2;
use IO::Handle;

($reader, $writer) = (IO::Handle->new, IO::Handle->new);
open2($reader, $writer, $program);
Esto hace que se ejecute $program de manera que su entrada queda conectada a $reader y su salida a $writer. El modo autoflush queda automáticamente establecido para el manejador de salida $writer.

También se puede llamar de esta otra forma:

$pid = open2(\*READ, \*WRITE, $program);
e incluso
$pid = open2(\*READ, \*WRITE, $program, "arg1", "arg2", ... );

También se puede llamar con el formato que vemos en la línea 30 del siguiente código. Los dos primeros argumentos representan manejadores de fichero.

lhp@nereida:~/Lperl/src/perl_networking/ch2$ cat -n open2noclose.pl
 1  #!/usr/bin/perl -w
 2  use strict;
 3  use FileHandle;
 4  use IPC::Open2;
 5  my $poetry1 =<< 'EOI1';
 6  while( exists( $the{'matrix'} ) ) {
 7    $the{'humanrace'} = "will never be free";
 8  }
 9  __EOT__
10  EOI1
11
12  my $poetry2 =<< 'EOI2';
13  $when=map{i$_}@wrong and time?is:out;
14  accept the, truth and wait;a while();
15  listen to, yourself;no fatal;$is=$around;
16  just; use next; chance and $build,$new_ground;
17  __EOT__
18  EOI2
19
20  sub getFromWriter {
21    my $got;
22    while ($got = <Reader>) {
23      last if $got =~ m{__EOT__};
24      $got =~ s/^ *//;
25      $got =~ s/\t/ /;
26      print "$got";
27    }
28  }
29
30  my $pid = open2(*Reader, *Writer, "cat -n" );
31  print Writer $poetry1, "\n";
32  getFromWriter();
33  print Writer $poetry2, "\n";
34  getFromWriter();
35  close(Reader);
36  close(Writer);
37  do {} while wait() > -1;
y el resultado de la ejecución:
lhp@nereida:~/Lperl/src/perl_networking/ch2$ ./open2noclose.pl
1 while( exists( $the{'matrix'} ) ) {
2   $the{'humanrace'} = "will never be free";
3 }
5
6 $when=map{i$_}@wrong and time?is:out;
7 accept the, truth and wait;a while();
8 listen to, yourself;no fatal;$is=$around;
9 just; use next; chance and $build,$new_ground;
lhp@nereida:~/Lperl/src/perl_networking/ch2$
La lectura y escritura simultáneas a otro programa puede conducir a atascos. Esto ocurre, si, por ejemplo, nos quedamos esperando a leer al mismo tiempo que lo hace el otro proceso.

La mayoría de los comandos Unix usan buffers en sus comunicaciones y salvo que el programa al otro lado haya sido escrito por nosotros no podemos garantizar la ausencia de atascos.



Subsecciones
Casiano Rodríguez León
2010-03-22