Perl EV模块创建周期性事件



我正在使用EV模块创建一个定时事件,该事件将在定义的时间间隔内无限期运行,这是我的定义间隔代码。

#!/usr/bin/perl
use strict;
use warnings qw/ all FATAL /;
use feature 'say';
use EV;
use Time::Piece 'localtime';
my $one_sec = EV::timer 1,1, sub {
   say "(1s)  Periodic event at ", localtime(EV::now)->hms;
};
my $five_sec = EV::timer 5, 5, sub {
  say "(5s)  Periodic event at ", localtime(EV::now)->hms;
};
EV::run;

我试图从散列引用中动态定义这些函数,通过循环来创建这些函数。

my $hash = {
    'one_sec'  => '1',
    'five_sec' => '5',
};

我用foreach循环遍历散列。

foreach my $key ( keys %$hash )
{
        my $key = EV::timer $hash->{$key},$hash->{$key}, sub {
        say "($hash->{$key})  Periodic event at ", localtime(EV::now)->hms;
        };
        EV::run;      
}

它是有效的,但只适用于第一次迭代,我不确定为什么?

非常感谢您的想法。

以下代码未经过测试。


你的代码有两个错误:

首先,在foreach循环的主体中启动事件循环,这将使它在foreach的第一次迭代中运行。然后它会被卡在那里,并且只会创建一个计时器。要解决此问题,需要将EV::run移动到foreach之外。

然而,它将不会做任何事情。这是因为事件循环没有任何作用。这是因为您在foreach的主体中用词法定义EV::timer对象。一旦完成一次迭代,该变量($key)将超出范围,破坏计时器对象。当创建完这两者后,它将只运行一个空的事件循环。除此之外,您还重新定义了$key,它已经是散列中的"one_sec""five_sec"字符串。

相反,您也需要将事件对象放在循环之外的某个地方(因为当您使用my时,每个块都会在Perl中创建一个词法范围,这是一个特性)。

你还应该使用更能说话的变量名,这样你就不会感到困惑。

#!/usr/bin/perl
use strict;
use warnings qw/ all FATAL /;
use feature 'say';
use EV;
use Time::Piece 'localtime';
my $config = {         # was $hash
    'one_sec'  => '1',
    'five_sec' => '5',
}
my $timers;
foreach my $key ( keys %$config ) {
    $timers->{$key} = EV::timer $config->{$key},$config->{$key}, sub {
        say "($config->{$key})  Periodic event at ", localtime(EV::now)->hms;
    };
}
EV::run;      

最新更新