Как я могу сказать Perl запускать некоторый код каждые 20 секунд? - PullRequest
12 голосов
/ 20 сентября 2010

Как я могу сказать Perl запускать некоторый код каждые 20 секунд?

Ответы [ 7 ]

21 голосов
/ 20 сентября 2010
for (;;) {
    my $start = time;
    # your code;
    if ((my $remaining = 20 - (time - $start)) > 0) {
        sleep $remaining;
    }
}
9 голосов
/ 20 сентября 2010
while (1) {
        sleep 20;
        <your code here>;
}
8 голосов
/ 20 сентября 2010

Хотя функция sleep будет работать для некоторых целей, если вы пытаетесь делать «каждые 20 секунд, навсегда», вам лучше использовать внешнюю утилиту, например cron.

В дополнение к уже упомянутой возможной проблеме дрейфа, если ваш sleep скрипт завершает работу (ожидаемо или нет), он не будет запускаться снова в следующие 20 секунд.

@ Blrfl - это правильно, и я чувствую себя застенчиво. Тем не менее, это достаточно легко преодолеть.

* * * * * /path/to/script.pl
* * * * * sleep 20 && /path/to/script.pl
* * * * * sleep 40 && /path/to/script.pl

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

7 голосов
/ 20 сентября 2010

Установите обработчик SIGALRM и отправляйте себе сигнал каждые 20 секунд с помощью alarm (см. perldoc -f alarm ):

$SIG{ALRM} = sub {
    # set up the next signal for 20 seconds from now
    alarm 20;

    # do whatever needs to be done
    # ...
};

Это будет дрейфовать со временем, так как каждый сигнал может быть задержан до секунды; если это важно, вместо этого создайте задание cron. Кроме того, произойдет еще больший сдвиг, если вашему другому коду потребуется более 20 секунд для запуска, так как только один таймер может считать сразу. Вы могли бы обойти это, порождая потоки, но на этом этапе я бы уже вернулся к простому решению cron.

Выбор правильного решения зависит от того, какую задачу нужно периодически выполнять, а вы не указали.

3 голосов
/ 21 сентября 2010

См. Расписание :: ByClock :

#!/usr/bin/perl

use strict; use warnings;
use Schedule::ByClock;

my $scheduler = Schedule::ByClock->new(0, 20, 40);

while ( defined( my $r = $scheduler->get_control_on_second ) ) {
    printf "%02d\n", $r;
}

Все оговорки, на которые указывали другие, все еще применяются, но я думаю, что модуль аккуратен

2 голосов
/ 05 сентября 2017
#!/usr/bin/perl -w

use strict;


# heartbeat
$SIG{ALRM} = sub {
    # set up the next signal for 20 second from now
    alarm(20);
    printf "<heartbeat/>\n";
};

alarm(20); # start timer
my $i = 0;
while(1) {
    $i++;
    printf "loop" . $i . "\n";
    sleep 2;
}

alarm(0);

printf "done!\n";

Выход:

loop1
loop2
loop3
loop4
loop5
loop6
loop7
loop8
loop9
loop10
<heartbeat/>
loop11
loop12
loop13
loop14
loop15
loop16
loop17
loop18
loop19
loop20
<heartbeat/>
2 голосов
/ 10 февраля 2016

Перейти с ..

while () {
  sleep 20;
  #Code here
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...