Perl FAQ 4.7: How can I call alarm() or usleep() from Perl?

Perl FAQ 4.7

How can I call alarm() or usleep() from Perl?

If you want finer granularity than 1 second (as usleep() provides) and have itimers and syscall() on your system, you can use the following. You could also use select().

It takes a floating-point number representing how long to delay until you get the SIGALRM, and returns a floating- point number representing how much time was left in the old timer, if any. Note that the C function uses integers, but this one doesn't mind fractional numbers.

# alarm; send me a SIGALRM in this many seconds (fractions ok)
# tom christiansen <tchrist@mox.perl.com>
sub alarm {
    require 'syscall.ph';
    require 'sys/time.ph';

    local($ticks) = @_;
    local($in_timer,$out_timer);
    local($isecs, $iusecs, $secs, $usecs);

    local($itimer_t) = 'L4'; # should be &itimer'typedef()

    $secs = int($ticks);
    $usecs = ($ticks - $secs) * 1e6;

    $out_timer = pack($itimer_t,0,0,0,0);  
    $in_timer  = pack($itimer_t,0,0,$secs,$usecs);

    syscall(&SYS_setitimer, &ITIMER_REAL, $in_timer, $out_timer)
    && die "alarm: setitimer syscall failed: $!";

    ($isecs, $iusecs, $secs, $usecs) = unpack($itimer_t,$out_timer);
    return $secs + ($usecs/1e6);
}


Other resources at this site: