ealeon
ealeon

Reputation: 12462

Perl polling a file handle?

use strict;
use warnings;

my $file = 'SnPmaster.txt';
open my $info, $file or die "Could not open $file: $!";

while( my $line = <$info>)  {   
    print $line;    
    last if $. == 2;
}

close $info;

Everywhere i look, the above is recommended to read from a file handle (while( my $line = <$info>)).

But is there a way to read instead of using a while loop?

open FH,
    "executable_that_prints_every_once_in_awhile"
    or die 'Cannot open FH';
while (1){
    # do something which doesnt get blocked by <FH>

    if (my $line from <FH>) {           <---- is there something like it?
        print $line;
    }

    last if eof <FH>;
}

For example, polling to see if there is an input from a file handle?

The problem with while( my $line = <$info>) is that it blocks so i cant do other things while waiting to get something from a FH

Upvotes: 1

Views: 537

Answers (1)

Sobrique
Sobrique

Reputation: 53488

Yes, there is. You need IO::Select and the can_read function.

Something like:

#!/usr/bin/perl
use strict;
use warnings;
use autodie;

use IO::Select;

my $selector = IO::Select->new();

open( my $program, "-|", "executable_that_prints_every_once_in_awhile" );
$selector->add($program);

foreach my $readable_fh ( $selector->can_read() ) {

    #do something with <$readable_fh>
}

Or alternatively - parallel code using threads or fork:

#!/usr/bin/perl
use strict;
use warnings;
use autodie;
use threads;

sub reader_thread { 
   open ( my $program, "-|", "executbale_file" );
   while ( my $line =  <$program> ) {
      print $line;
   }
}

threads -> create ( \&reader_thread );

while ( 1 ) {
   #do something else
}

#sync threads at exit - blocks until thread is 'done'. 
foreach my $thr ( threads -> list ) {
  $thr -> join();
}

Generally I would suggest threading when you need to do more than a trivial amount of IPC, and forking for general performance. Thread::Queue is quite a good way of passing data back and forth between threads, for example. (See: Perl daemonize with child daemons if you think you want to go that route)

Upvotes: 5

Related Questions