http://www.perlmonks.org?node_id=30090

gregorovius has asked for the wisdom of the Perl Monks concerning the following question:

I want to be able to time out when reading a handle with the angle operator:
use English; $TIMEOUT_FOR_ANGLE_IO = 2.35; my $line = <STDIN>; print 'you took too long' unless defined($line);
Where $line would be undefined if a line is not read within the time specified, where that variable would be a perl predefined global. Day dreaming aside, what would the easiest way to accomplish this be? (and with a hi-res timer, please :-) I guess I could start by looking at signal handlers. Thanks in advance for any help.

Gregorovius

Replies are listed 'Best First'.
Re: timeout for ?
by ar0n (Priest) on Aug 29, 2000 at 13:06 UTC
    From "Advanced Perl Programming":
    $SIG{ALRM} = \&timed_out; eval { alarm(10); $buf = <>; alarm(0); }; if ($@ =~ /BLAH/) { print "Timed out."; } sub timed_out { die "BLAH" }
    update
    this will wait ten seconds for someone to enter something. the alarm(0) is to reset the timer if something does get entered (so &timed_out won't get called).

    if you want high resolution timing (like 2.35), ye olde dromedary suggests using syscall to call the system timer routines (itimer).

    -- ar0n || Just Another Perl Joe

      Ye olde dromedary is old.

      use Time::HiRes;

              - tye (but my friends call me "Tye")
Re: timeout for ?
by gregorovius (Friar) on Aug 29, 2000 at 21:41 UTC
    What would the best way of incorporating Time::HiRes be? I could think of forking off a child who would be in charge of generating the alarm signal (using kill) to the parent, after sleeping for a time using the Time::HiRes sleep function.

    This feels like a clunky solution, so is there a way for a Perl script to ask the OS for a signal with better resolution?

    Also, alarm() is sadly unimplemented on Windows NT, which is (idem) the OS I'm currently using. Thanks!

    Greg

      Time::HiRes includes ualarm(), so no need to roll your own.

      For WinNT, I was going to relunctantly suggest Win32::Console but it doesn't seem to offer this like I thought it did. (Reluctantly, not because it is a yucky module (it is well made), but because I hate resorting to such OS-specific modules -- and it only works for reading from consoles.) I'd love to hear of a more portable solution that works on NT.

              - tye (but my friends call me "Tye")
Re: timeout for ?
by ncw (Friar) on Aug 30, 2000 at 14:44 UTC
    You could try Term::ReadKey it seems to do exactly what you want - ie non-blocking IO with a timeout.

    Looks like it works on Win/Unix also.

    Actually reading the man page a bit more carefully I see that the method you really want to use doesn't work under windows :-(