This code was working using open "-|" and STDOUT, but debugging messages in sub-modules forced the need to use explicit filehandles in the child process and I converted to IO::Pipe. Please note that this is a simplified test version of the production application, that's why it doesn't make real world sense. This is being run on Solaris 2.8 on a standard install of Perl 5.6.1. Also, read_line() is a homegrown sysread() wrapper I wrote. Thanks in advance! Brian Goad
use IO::Select; use IO::Pipe; use IO::Handle; @connect = ("3","2","1"); # "main" child my $select_ch = new IO::Select; foreach $msg (@connect) { # for each write, fork a child if($msg) { # fork and open child for reading my $pipe = new IO::Pipe; if(my $pid = fork() ) { #parent $fh = $pipe->reader(); $debug && print "$$ forked $pid\n"; $fh->blocking(0); # set non-blocking I/O $debug && print "adding filehandle ($fh)\n"; $select_ch->add($fh); } else { #child my $childhandle = $pipe->writer(); sleep $msg; print $childhandle "$msg,response,$mt\n"; exit 0; #kill the child process } } } # done with processing this read # here we read for responses from the filehandles my @readyfiles; #array for select to populate my $rh; # a readable filehandle while( @readyfiles = $select_ch->can_read() ) { foreach $rh (@readyfiles) { # read from filehandle, send back string my $child_resp_string = ''; print "calling read_line\n"; my $bytes = read_line(\$child_resp_string,$rh); $debug && print "returned $child_resp_string\n"; # only one read per handle, so close $select_ch->remove($rh); $rh->close; my $cnt = $select_ch->count(); $debug && print "$cnt handles left to read\n"; } } print "exiting...\n"; exit 0;
In reply to IO::Pipe and IO::Select by brinogordon
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |