Как создать прерывание через х секунд в Perl? - PullRequest
0 голосов
/ 01 ноября 2018

Позвольте мне объяснить задачу с примером кода:

#!/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";
}

Вместо sleep у меня есть код, который отправляет данные в массив. Массив будет гарантированно заполнен необходимыми данными в течение `x секунд.

Вопрос: как распечатать массив после x секунды, без использования sleep (неблокирующий способ)?

Насколько я понимаю, самый простой способ установить таймер в perl - это использовать $SIG{ALRM}. Но что делать, если мне не нужен таймер (я не могу использовать sleep), мне просто нужно установить одно прерывание, которое должно запускаться через предварительно определенное количество секунд? Может быть, я должен использовать SIGINT для этой задачи?

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 02 ноября 2018

В этом весь смысл alarm! Просто используйте более подходящий обработчик сигнала.

my @x;

$SIG{ALRM} = sub {
   print("$_\n") for @x;
   $SIG{ALRM} = undef;
};

alarm(10);

...
0 голосов
/ 01 ноября 2018

Чтобы создать свои собственные прерывания, вам нужно два потока выполнения. Один из способов сделать это - запустить дочерний процесс, который сообщит своему родителю, когда будет выполнено какое-либо условие.

$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 секунд после вызова fork ваш основной скрипт остановит свою работу, выполнит код в подпрограмме с именем code_to_run_after_interrupt, а затем возобновит основной поток выполнения.

(я использую SIGUSR1 здесь, потому что обработка SIGINT может сделать вас неспособным использовать Ctrl-C для остановки вашей программы)

...