I had asked a question a few weeks ago about implementation of a non-blocking one parent-many child pipe, which was ably answered by @mob here
However, I've noticed that if a child posts more than one message before exiting, the parent only gets the first one if it reads a little later.
Example code:
use IO::Handle;
use POSIX ':sys_wait_h';
pipe(READER,WRITER);
WRITER->autoflush(1);
sub child_process {
close READER; # also a best but optional practice
srand($$);
my $id = 0;
sleep 1 + 5*rand();
$id++;
print "Child Pid $$ sending message $id now...\n";
print WRITER "$id:Child Pid $$ is sending this - Message 1\n";
print WRITER "$id:Child Pid $$ is sending this - Message 2\n";
exit 0;
}
if (fork() == 0) {
child_process();
}
# parent
my ($rin,$rout) = ('');
vec($rin,fileno(READER),1) = 1;
while (1) {
# non-blocking read on pipe
my $read_avail = select($rout=$rin, undef, undef, 0.0);
if ($read_avail < 0) {
if (!$!{EINTR}) {
warn "READ ERROR: $read_avail $!\n";
last;
}
} elsif ($read_avail > 0) {
chomp(my $line = <READER>);
print "Parent Got $$: '$line'\n";
} else {
print STDERR "No input ... do other stuff\n";
}
sleep 5;
}
close WRITER; # now it is safe to do this ...
Expected output:
I should get both messages.
What I get: Only the first message
No input ... do other stuff
No input ... do other stuff
Child Pid 8594 sending message 1 now...
Parent Got 8593: '1:Child Pid 8594 is sending this - Message 1'
No input ... do other stuff
This is supposed to be a non-blocking read, so home come it can't pick up the data on the next iteration? Is it because the child exited? I tried doing a while (chomp(my $line = <READER>)) in the parent, but that blocks, which I can't have.