Dear wise monks,

I am trying to communicate with several child processes, each of which calls a web service and then writes a small amount of data on STDOUT. I want to read from all of them that I can, and then declare the rest timed out. The problem is that the open2 and IO::Select don't seem to be reliable.

I have trimmed the problem down to a single-child case. Sometimes I am able to read the process output, and sometimes it times out with nothing. I've even seen the child's output appear on the regular STDOUT as if it had never been redirected, while the parent process gets an empty buffer back!

Do you have any ideas about what could be going wrong, or suggestions for better ways to do this?

A code example is below.

use strict; use IPC::Open2; use IO::Select; sub sys_read { my ($fh) = @_; my $blksize = 4096; my $len; my $data = ""; my $buff; READS: while ($len = sysread($fh, $buff, $blksize)) { if (!defined $len) { next READS if $! =~ /^Interrupted/; return undef; } $data .= $buff; } return $data; } # The tester.pl script calls a web service using lines like this: #my $ua = LWP::UserAgent->new; #my $response = $ua->request(POST $uri, [ackhost => $ackhost, # data => $data, # pid => $pid]); my @command = ("/usr/bin/perl", "./tester.pl"); my($wtr, $rdr); # trying an autovivification this time. my $pid = open2($rdr, $wtr, @command); close $wtr; my @lst; push @lst, $rdr; my $timeout = 4.0; my @ready; READLOOP: while(@ready = IO::Select->new(@lst)->can_read($timeout)) { HANDLELOOP: foreach my $rh (@ready) { # This might block and sysread might be better, but let's see +.. my $buff = sys_read($rh); print "buff is *$buff*\n"; close $rh; @lst = (); } } if (scalar(@lst)) { print "Timed out with nothing this time\n"; }

In reply to open2 unreliable? by Anonymous Monk

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.