use warnings; use strict; use Time::HiRes qw/ clock_gettime clock_nanosleep CLOCK_REALTIME TIMER_ABSTIME /; die "Don't have nanosleep" unless Time::HiRes::d_nanosleep(); use Time::HiRes qw/usleep/; # just for this fake "myfunc" sub myfunc { printf "fired %.2f\n", clock_gettime(CLOCK_REALTIME); my $delay_us = int(rand 100000)+10000; # 110000us = 0.11s printf "delay %.2fs\n", $delay_us/1e6; usleep $delay_us; } my $next_s = int(clock_gettime(CLOCK_REALTIME))+1; my $interval_s = 0.1; my $run = 1; $SIG{INT} = sub { $run = 0 }; while ($run) { my $now_s = clock_gettime(CLOCK_REALTIME); $next_s += $interval_s while $next_s < $now_s; clock_nanosleep(CLOCK_REALTIME, $next_s*1e9, TIMER_ABSTIME); myfunc(); }