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

イベントシステムの考え方は、特定の1つのイベントの待機をブロックする線形コードを作成するのではなく、イベントが発生したときに何をするかについてハンドラーを設定し、これらのイベントのいずれかが発生するのを待つことです。イベントフレームワークは通常、イベントが発生したときにこれらのイベントハンドラーにディスパッチします。トリックは、ハンドラーを設定し、それを待つことです。

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;

AnyEventとAnyEvent::Filesys :: Notificationを含むこのスニペットは、それを行う1つの方法にすぎません。基本的に、フレームワークに関係なく、ほとんどの場合同じ方法です。コールバックを使用してウォッチャーをセットアップし、「メインループ」に入ります。

于 2012-05-23T05:55:54.620 に答える