There's two ways I can think of to do it - one is via threading your perl, to make your 'reading STDIN' run in parallel. Something like:
#!/usr/bin/perl
use strict;
use warnings;
use threads;
use Thread::Queue;
my $input_q = Thread::Queue -> new();
sub stdin_reader
{
while ( my $line = <STDIN> )
{
if ( defined $input_q -> pending() )
{
$input_q -> enqueue ( $line );
}
else
{
last;
}
}
}
sub doing_stuff_thread
{
my $count = 0;
while ( $count < 10 )
{
my $item = $input_q -> dequeue_nb();
if ( defined $item )
{
print "Got: $item";
$count++;
}
else
{
print "Doing something else, because nothing on STDIN\n";
print "Pending items:", $input_q -> pending(), "\n";
sleep 1;
}
}
$input_q -> end();
}
threads -> create ( \&stdin_reader );
threads -> create ( \&doing_stuff_thread );
foreach my $thr ( threads -> list() )
{
print "Waiting for ",$thr -> tid()," to join\n";
$thr -> join();
}
That works, although bear in mind that 'STDIN' is being read line by line, so you need to put carriage returns in. (you can't do 'readkey' style). (And also - you may find 'Thread::Queue' isn't 'standard', but I'm sure you can figure out how to do something useful with thread::shared and lock instead.
The other way I can think of involves using IO::Select. Or perhaps like this node: Here
#!/usr/bin/perl
use strict;
use warnings;
use IO::Handle;
use IO::Select;
my $nb_stdin = new IO::Select( *STDIN );
while ( 1 )
{
if ( $nb_stdin -> can_read(0) )
{
my $line = <STDIN>;
print "Got: ", $line,"\n";
}
else
{
print "Nothing on STDIN, doing something else\n";
sleep 1;
}
}
This doesn't seem to work properly on Win32/Activestate though - I believe I've seen something to the effect that IO::Select doesn't work on non-sockets on W32. YMMV
|