Monk, I am in a maze of twisty interprocess communications, all different.

I have a process that spawns a number of kids. It reads a line from a data file, and then writes that line to each kid. A kid may choose to reply, or it may remain silent. I've been looking for the best way to handle this. I can assume that if the kid doesn't reply within one second, it's as if it never will.

I've been perusing the Cookboot, perlipc and IPC::Open2 and I can't get no satisfaction (woah-ho-ho). I hesitate to show the code I've been toying with, because it will show what an amateur I am at this. I have done quite a bit of this sort of stuff, but I've always been able to get away with the fact that the problem at hand mapped nicely to one of the examples. I think the fact that a child may remain silent is the trickiest thing (as in: non-blocking reads).

It seemed to me that the nicest solution was to use socketpair, as per perlipc. But after I started to bend the example more into the shape I wanted it to be, I think I ran into a wall of [bs]uffering.

So here's the code:

#! /usr/bin/perl use strict; use constant DUMMY => 1; use Socket; use IO::Handle; socketpair(CHILD, PARENT, AF_UNIX, SOCK_STREAM, PF_UNSPEC) or die "soc +ketpair client: $!"; CHILD->autoflush(1); PARENT->autoflush(1); if (my $kid = fork) { close PARENT; for my $key( @ARGV ) { print "parent($$) send [$key]\n"; print CHILD "$key\n"; chomp(my $line = <CHILD>); print "parent($$) recv [$line]\n"; } close CHILD; waitpid($kid,0); } else { die "cannot fork: $!" unless defined $kid; close CHILD; if( DUMMY ) { while( chomp(my $line = <PARENT>) ) { print "child($$) recv [$line]\n"; select undef, undef, undef, 0.2; if( rand() < 0.5 ) { my $now = "$line " . time; print "child($$) send [$now]\n"; print PARENT "$now\n"; } } close PARENT; } else { exec qw{ /bin/foo -c bar } or die "child could not exec: $!\n" +; } }

The above works if DUMMY is set to 1 and the kid replies each time. And if I set DUMMY to 0, in order to make the kid exec the program I really want to use it dies with a sullen Broken pipe, and I don't understand why. I know I need a select loop to see if there are handles with data waiting on them, but when I read the man page I feel like a rabbit caught in headlights.

What's more, the code above is for one kid, I need an array of them.

My dream is that I would be able to hide all this nasty stuff behind subroutines, which would in turn let me Memoize them, because it turns out that I ask the kids the same question over and over again (a bit like real life, eh?)

Thanks for any clues I can use.

update: bbfu's remark taken: this is not for Win32, so I'm not worried about Windowisms


In reply to Non-blocking IPC to and from multiple children by grinder

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.