Perl Monks, any help will be much appreciated....I've got a server that use IO::Pipe to open up filehandles to forked sub processes and then loaded into an IO::Select object for reading. The issue I'm having is that filehandles generated by IO::Pipe do not seem to be handled properly by the can_read() method of IO::Select when the can_read is the condition in a while loop. The code below will read the first filehandle made available, however the while loop then exits, even with two filehandles still in the select set (as confirmed by the count() method).

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

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.