2

我想弄清楚 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(),但目前我坚持将其放入事件循环中。

另外,我想添加某种形式的与程序的交互,可能通过套接字(另一个观察者)。

谢谢

4

2 回答 2

5

事件系统的想法不是编写阻止等待某个特定事件的线性代码,而是设置处理程序以在事件发生时做什么,然后等待这些事件中的任何一个发生。当事件发生时,事件框架通常会分派给这些事件处理程序。然后诀窍是设置处理程序,然后等待它。

EV 和 AnyEvent 都将支持这种事情。还要看的东西是POE和。IO::AsyncReflex

在这些中的任何一个中,大体的想法都是一样的,但我会举一个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 秒运行一次指定的函数。在程序的底部,main$loop->run方法会在适当的时间分派给事件处理程序。

于 2012-05-22T21:07:44.047 回答
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;

This snippet with AnyEvent and AnyEvent::Filesys::Notify is just one way to do it. Basically it's almost always the same way, regardless of your framework: Setup your watchers with your callbacks and enter your "mainloop".

于 2012-05-23T05:55:54.620 回答