7.13. Reading from Many Filehandles Without BlockingProblemYou 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 $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
The first three arguments to $rin = ''; vec($rin, fileno(FILEHANDLE), 1) = 1; $nfound = select($rin, undef, undef, 0); # just check if ($nfound) { $line = <FILEHANDLE>; print "I read $line"; }
This code isn't perfect, though. If someone connects and sends a character but never sends a newline, your program will block in the
The IO::Select module hides the bit-vectors from you.
Don't mix calls to four-argument If you want to read whatever is available on a socket or pipe and return immediately, see Recipe 7.14. If you're trying to do non-blocking reads on a terminal, see Recipes Recipe 15.6 and Recipe 15.8 . See Also
The |
|