in reply to Re^2: Read from a Linux pipe hangs.
in thread Read from a Linux pipe hangs.

You can read non blocking using select, and looping trough select until there is some data to read.
Reading using the diamond operator or sysread is blocking. The difference between the two is that using sysread you can control how much data to read at once.
Also, i see you are using cat some_file|consumer.pl, so i don't understand why you are looping and sleeping in consumer, as cat happens to give you data only once ;-) (if you "cat" a closed file)
I also think that you are using the wrong approach here. If you want the consumer to read data at certain amounts of time, a better approach IMHO is to do blocking reads in a while(1) without sleeping, and feeding the consumer at the needed intervals. I.E:
shell> for ((;;)); do cat /usr/share/dict/words;sleep 10 ;done |./cons +umer.pl
Note that by not running cat just once, you will not receive end-of-file, and as such you need to read using sysread from the consumer.
Dodge This!

Replies are listed 'Best First'.
Re^4: Read from a Linux pipe hangs.
by dmor4477 (Initiate) on Feb 24, 2005 at 12:24 UTC
    Hi,
    Using Select and syswrite(), the system works better but there's a buffer problem:
    
    If the producer prints the first line, the consumer only reads the first character. When the producer prints the
    second line, then the consumer reads the rest of the fist 
    line characters but can't read the second line so the 
    consumer never reads the last line.
    
    
    Here's the code and the result that illustrates the problem:
    
    #producer.pl                                                                                                                            
    my $i;
    for $i (0 .. 3){
            syswrite(STDOUT,"Hello_$i\n",length("Hello_$i\n"));
            $i=$i+1;
            sleep(5);
    }
    while(1){} #The real producer never ends.
    
    #Consumer.pl
    $select = IO::Select->new();                                                                                                                            
    $select->add(\*STDIN);                                                                                                                           
    while (1){
        if(@ready=$select->can_read(0)){
           if(read($ready0, $tmp, 1))
           {
                    print "Data read $tmp\n";
                    if ($tmp =~ /\n|\r|\r\n/o){
                             print "$line\n";
                             $line = "";
                    }else{
                            $line.=$tmp;
                    }
           }
                                                                                                                                       if(eof($ready0)){
              last;
           }
       }else{
           print "Process.\n";
           sleep(5);
       }
    }
    
    #Result
    ./producer.pl | ./consumer.pl
    Data read H
    Process.
    Data read e
    Data read l
    Data read l
    Data read o
    Data read _
    Data read 0
    Data read
     
    Hello_0
    Process.
    Data read H
    Data read e
    Data read l
    Data read l
    Data read o
    Data read _
    Data read 1
    Data read
     
    Hello_1
    Process.
    Data read H
    Data read e
    Data read l
    Data read l
    Data read o
    Data read _
    Data read 2
    Data read
     
    Hello_2
    Process.
    Process.
    
    If the producer dies, the consumer can read the last line,
    but it never happens.
    
    Thanks,
    
Re^4: Read from a Linux pipe hangs.
by dmor4477 (Initiate) on Feb 24, 2005 at 12:06 UTC
    Hi,
    Using Select and syswrite(), the system works better but there's a buffer problem:
    
    If the producer prints the first line, the consumer only reads the first character. When the producer prints the
    second line, then the consumer reads the rest of the fist 
    line characters but can't read the second line so the 
    consumer never reads the last line.
    
    
    Here's the code and the result that illustrates the problem:
    
    #producer.pl                                                                                                                            
    my $i;
    for $i (0 .. 3){
            syswrite(STDOUT,"Hello_$i\n",length("Hello_$i\n"));
            $i=$i+1;
            sleep(5);
    }
    while(1){} #The real producer never ends.
    
    #Consumer.pl
    $select = IO::Select->new();                                                                                                                            
    $select->add(\*STDIN);                                                                                                                           
    while (1){
        if(@ready=$select->can_read(0)){
           if(read($ready[0], $tmp, 1))
           {
                    print "Data read $tmp\n";
                    if ($tmp =~ /\n|\r|\r\n/o){
                             print "$line\n";
                             $line = "";
                    }else{
                            $line.=$tmp;
                    }
           }
                                                                                                                                       if(eof($ready[0])){
              last;
           }
       }else{
           print "Process.\n";
           sleep(5);
       }
    }
    
    #Result
    ./producer.pl | ./consumer.pl
    Data read H
    Process.
    Data read e
    Data read l
    Data read l
    Data read o
    Data read _
    Data read 0
    Data read
     
    Hello_0
    Process.
    Data read H
    Data read e
    Data read l
    Data read l
    Data read o
    Data read _
    Data read 1
    Data read
     
    Hello_1
    Process.
    Data read H
    Data read e
    Data read l
    Data read l
    Data read o
    Data read _
    Data read 2
    Data read
     
    Hello_2
    Process.
    Process.
    
    If the producer dies, the consumer can read the last line,
    but it never happens.
    
    Thanks,
    
      You read one character a time, so there is no problem. See read for details
      Maybe i should have been more explicit. What i did is, reading one character at a time, and adding it to $line. Until i find an end of line.
      That's why i did sysread, reading just one byte a time. As i said, the producer never ending, you will never get eof (only if the producer knows to send eof).
      Don't use while(1){} instead of sleep ;-)
      Dodge This!