Reading from Many Filehandles Without Blocking
Problem
You want to learn whether input is available to be read, rather than blocking for input as < > does. This is useful when reading from pipes, sockets, devices, and other programs.
Solution
Use select with a timeout value of
seconds, if you’re comfortable with manipulating bit-vectors
representing file descriptor sets:
$rin = '';
# repeat next line for all filehandles to poll
vec($rin, fileno(FH1), 1) = 1;
vec($rin, fileno(FH2), 1) = 1;
vec($rin, fileno(FH3), 1) = 1;
$nfound = select($rout=$rin, undef, undef, 0);
if ($nfound) {
# input waiting on one or more of those 3 filehandles
if (vec($rout,fileno(FH1),1)) {
# do something with FH1
}
if (vec($rout,fileno(FH2),1)) {
# do something with FH2
}
if (vec($rout,fileno(FH3),1)) {
# do something with FH3
}
}The IO::Select module provides an abstraction to hide the bit-vector operations:
use IO::Select;
$select = IO::Select->new();
# repeat next line for all filehandles to poll
$select->add(*FILEHANDLE);
if (@ready = $select->can_read(0)) {
# input waiting on the filehandles in @ready
}Discussion
The select function is really two functions in
one. If you call it with one argument, you change the current default
output filehandle (see Section 7.12). If you call it
with four arguments, it tells you which filehandles have input
waiting or are ready to receive output. This recipe only deals with
four-argument select.
The first three arguments to select are strings containing bit-vectors. Each ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access