我想弄清楚Perl中的事件循环?
目前我的程序是这样的:
while(my $event = wait_for_event()){
handle_event($event);
try_to_do_something();
}
wait_for_event阻止。
我想弄清楚我是否可以使用EV或AnyEvent(AE)或其他东西来添加另一个事件观察者。
例如,我希望能够每2秒调用一次try_to_do_something(),但目前我不能将它放入事件循环中。
另外,我想通过套接字(另一个观察者)添加某种形式的与程序的交互。
谢谢
答案 0 :(得分:5)
事件系统的想法不是编写阻止等待一个特定事件的线性代码,而是设置处理程序以便在事件发生时做什么,然后等待任何这些事件发生。事件框架通常会在事件发生时分派给这些事件处理程序。然后诀窍是设置处理程序,然后等待它。
EV和AnyEvent都支持这种事情。另外需要注意的事项有POE
,IO::Async
和Reflex
。
总体思路在任何一个方面都会大致相同,但我会在IO::Async
中给出一个例子,因为我知道它最好,主要是因为我写了它。
use IO::Async::Loop;
use IO::Async::Timer::Periodic;
my $loop = IO::Async::Loop->new;
$loop->add( IO::Async::Timer::Periodic->new(
interval => 2,
on_tick => \&try_to_do_something
)->start );
# Perhaps here you'd add your socket watcher, using an
# IO::Async::Handle or ::Stream or something else
$loop->run;
$loop->add
方法将通知程序对象安装到循环中,在这种情况下,循环计时器每2秒运行指定的函数。在程序的底部,主$loop->run
方法然后在适当的时间调度到事件处理程序。
答案 1 :(得分:1)
也许你正在尝试做这样的事情?
use AnyEvent;
use AnyEvent::Filesys::Notify;
sub try_to_do_something { say "every two seconds" }
sub handle_event { say $_->path." ".$_->type for @_ }
my $n = AnyEvent::Filesys::Notify->new(
dirs => ['/tmp'],
interval => 0.5,
filter => sub { 1 },
cb => sub { handle_event(@_) },
);
my $w = AE::timer 0, 2, sub {try_to_do_something};
AnyEvent->condvar->recv;
使用AnyEvent和AnyEvent :: Filesys :: Notify的这个片段只是一种方法。基本上它几乎总是以同样的方式,无论你的框架如何:用你的回调设置你的观察者并输入你的“mainloop”。