Let me explain task with code example:
#!/usr/bin/perl
use strict;
use warnings;
my $t = 3;
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; # NB: \n required
print "Start $t\n";
alarm(10);
sleep($t); # instead of this I have some data that collect code
alarm(0);
print "done with $t\n";
};
if ($@) {
die unless $@ eq "alarm\n";
print "timeout\n";
}
Instead of sleep
I have some code that push data to array. Array will be guaranteed filled by needed data during `x seconds.
Question: how to print array after x
second, without using sleep
(non-blocking way) ?
As far as I understand simplest way to set timer in perl is to use $SIG{ALRM}
. But what to do if I don't need timer (can't use sleep
), I just need to set one interrupt that must run after pre-defined amount of seconds ? Maybe I should use SIGINT
for this task?
Any help appreciated.
To create your own interrupts, you need two threads of execution. One way to do this is to launch a child process that will signal its parent when some condition is met.
$SIG{USR1} = \&code_to_run_after_interrupt;
my $ppid = $$; # process id of parent
if (fork() == 0) {
# child process
sleep 15;
kill 'USR1', $ppid;
exit;
}
... main execution thread
15 seconds after the fork
call, your main script will stop what it's doing, execute the code in a subroutine named code_to_run_after_interrupt
, and then resume the main thread of execution.
(I use SIGUSR1
here because handling SIGINT
may make you unable to use Ctrl-C
to stop your program)