Reputation: 12462
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
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