pipe - non blocking read? (fork/Win32)

Discussion in 'Perl Misc' started by Stuart Moore, Jul 2, 2003.

  1. Stuart Moore

    Stuart Moore Guest

    Hi, I'm using windows, I want to create a new process using fork (in
    Activestate's Perl 5.6.x for some x) and communicate between the parent
    and child using pipes. But I'd like the parent to be able to check if
    there was anything waiting for it in the pipe, and if not, come back and
    check later.

    Is this possible? If not any suggestions on what I can do?

    Stuart
    Stuart Moore, Jul 2, 2003
    #1
    1. Advertising

  2. Stuart Moore

    Stuart Moore Guest

    On Wed, 2 Jul 2003, Greg Bacon wrote:
    > In article <>,
    > Stuart Moore <> wrote:
    >
    > : Hi, I'm using windows, I want to create a new process using fork (in
    > : Activestate's Perl 5.6.x for some x) and communicate between the parent
    > : and child using pipes. But I'd like the parent to be able to check if
    > : there was anything waiting for it in the pipe, and if not, come back and
    > : check later.
    > :
    > : Is this possible? If not any suggestions on what I can do?
    >
    > Is there a reason you'd prefer pipes to, say, sockets?


    Um, no. Can Socekts do that? In which case how? A brief trawl through the
    documentation gave me nothing.

    Thank you very much
    Stuart
    Stuart Moore, Jul 2, 2003
    #2
    1. Advertising

  3. Stuart Moore

    Greg Bacon Guest

    In article <>,
    Stuart Moore <> wrote:

    : On Wed, 2 Jul 2003, Greg Bacon wrote:
    :
    : > Is there a reason you'd prefer pipes to, say, sockets?
    :
    : Um, no. Can Socekts do that? In which case how? A brief trawl through
    : the documentation gave me nothing.

    At the bottom of the IO::Select manpage is a socket server. Here's
    an adaptation of that:

    #! /usr/local/bin/perl

    use warnings;
    use strict;

    use IO::Select;
    use IO::Socket;

    sub child {
    my $port = shift;

    my $s = IO::Socket::INET->new(PeerAddr => "localhost:$port");
    die "$0: failed to create socket in child" unless $s;

    for (1 .. 5) {
    sleep rand 10;

    print $s "message #$_\n";
    }
    }

    sub do_something_else {
    print "parent: Doing something else...\n";
    sleep rand 5;
    print "parent: Done.\n";
    }

    sub check_sockets {
    my $lsn = shift;
    my $sel = shift;

    my @ready = $sel->can_read(0);
    foreach my $fh (@ready) {
    if ($fh == $lsn) {
    # Create a new socket
    my $new = $lsn->accept;
    $sel->add($new);
    }
    else {
    # Process socket
    my $fd = fileno $fh;

    if (my $input = <$fh>) {
    chomp $input;
    print "parent: fd $fd: [$input]\n";
    }
    else {
    $sel->remove($fh);
    $fh->close;

    $lsn->close;
    }
    }
    }
    }

    ## main
    my $port = 8080;
    my $lsn = new IO::Socket::INET(Listen => 1, LocalPort => $port);
    my $sel = new IO::Select($lsn);

    my $pid = fork;
    die "$0: fork: $!" unless defined $pid;

    unless ($pid) {
    child $port;
    exit 0;
    }

    while ($lsn->opened) {
    check_sockets $lsn, $sel;

    do_something_else;
    }

    Hope this helps,
    Greg
    --
    And when I heard the baby-talk coming out of George W. Bush's mouth in front
    of Congress, there's this Axis of Evil, Iran, Iraq and ... North Korea? I
    mean, he doesn't know where these places are, much less what evil is . . .
    -- Gore Vidal
    Greg Bacon, Jul 2, 2003
    #3
  4. Greg Bacon wrote:
    [snip]
    > my @ready = $sel->can_read(0);
    > foreach my $fh (@ready) {

    [snip]
    > if (my $input = <$fh>) {


    Don't do that.

    --
    $a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
    );{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6
    ]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}
    Benjamin Goldberg, Jul 4, 2003
    #4
  5. Stuart Moore

    Greg Bacon Guest

    In article <>,
    Benjamin Goldberg <> wrote:

    : Greg Bacon wrote:
    :
    : [snip]
    : > my @ready = $sel->can_read(0);
    : > foreach my $fh (@ready) {
    : [snip]
    : > if (my $input = <$fh>) {
    :
    : Don't do that.

    Why not?

    Greg
    --
    What light is to the eyes -- what air is to the lungs -- what love is to
    the heart, liberty is to the soul of man.
    -- Robert Green Ingersoll
    Greg Bacon, Jul 6, 2003
    #5
  6. Greg Bacon wrote:
    >
    > In article <>,
    > Benjamin Goldberg <> wrote:
    >
    > : Greg Bacon wrote:
    > :
    > : [snip]
    > : > my @ready = $sel->can_read(0);
    > : > foreach my $fh (@ready) {
    > : [snip]
    > : > if (my $input = <$fh>) {
    > :
    > : Don't do that.
    >
    > Why not?


    The readline (aka <>) operator does the following:
    1a/ It scans it's internal buffer for the $/ string, and if
    it finds it,
    1b/ Removes (and returns) everything in it's buffer up to and
    including the $/. Anything after the $/ remains in the buffer.
    2/ After we looked for and didn't find $/, it uses the C read()
    function to get data from the filedescriptor and adds it to it's
    internal buffer.
    3/ Go back to step 1.

    The can_read method of IO::Select tells us whether or not the file
    descriptor has more bytes available... that is, whether or not calling
    the C read() function on that fd would block.

    Now, let's suppose that the other end of the pipe sends us data faster
    than we read it... e.g., suppose that it sends us three lines in the
    time it took us to process one.

    What happens?

    Select's can_read says the pipe is ready to read from, then we call
    readline(), which read()s *all* of the bytes that are in the pipe (in
    the file descriptor) into the internal byffer. Then, we remove one $/
    delimited line from that buffer, leaving two in the buffer. Then, we
    call can_read again... and there are no bytes in the pipe! There are
    bytes in the buffer, but none to be read from the file descriptor.

    Alas, can_read knows nothing of the filehandle's internal buffer, it can
    only examine the filedescriptor.

    As a result, we won't call <> the extra two times that we should, and
    thus those two lines never get read and printed out.

    Well, maybe they'll get printed the *next* time a line gets printed to
    the other end of the pipe... but that could be quite a long while after
    those two lines were sent. It wouldn't be a good thing if we were only
    able to read data many minutes after it was sent, would it?

    Further, consider if we're doing two-way communication, not just
    one-way... suppose the process on the other end of the pipe wants to
    read something from us, before it will send anything else to us. We're
    in trouble... we can't see what it sent, until it sends us "extra", and
    it won't send us extra, until we see and respond to what it sent. This
    is known of as deadlock.

    --
    $a=24;split//,240513;s/\B/ => /for@@=qw(ac ab bc ba cb ca
    );{push(@b,$a),($a-=6)^=1 for 2..$a/6x--$|;print "$@[$a%6
    ]\n";((6<=($a-=6))?$a+=$_[$a%6]-$a%6:($a=pop @b))&&redo;}
    Benjamin Goldberg, Jul 7, 2003
    #6
  7. (Greg Bacon) wrote in message news:<>...
    > In article <>,
    > Benjamin Goldberg <> wrote:
    >
    > : Greg Bacon wrote:
    > :
    > : [snip]
    > : > my @ready = $sel->can_read(0);
    > : > foreach my $fh (@ready) {
    > [snip]
    > : > if (my $input = <$fh>) {
    > :
    > : Don't do that.
    >
    > Why not?


    perldoc -f select

    <snip>

    WARNING: One should not attempt to mix buffered I/O (like "read"
    or <FH>) with "select", except as permitted by POSIX, and even
    then only on POSIX systems. You have to use "sysread" instead.



    >
    > Greg
    Bryan Castillo, Jul 7, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Hendra Gunawan
    Replies:
    1
    Views:
    12,516
    Allan Herriman
    Apr 8, 2004
  2. Andre Kelmanson

    blocking i/o vs. non blocking i/o (performance)

    Andre Kelmanson, Oct 10, 2003, in forum: C Programming
    Replies:
    3
    Views:
    922
    Valentin Tihomirov
    Oct 12, 2003
  3. placid
    Replies:
    8
    Views:
    1,352
    Durumdara
    Aug 4, 2006
  4. Serge Savoie
    Replies:
    4
    Views:
    263
    Serge Savoie
    Oct 1, 2008
  5. Kevin Walzer
    Replies:
    2
    Views:
    130
    Terry Reedy
    Dec 22, 2012
Loading...

Share This Page