Perl AnyEventの簡単な紹介と入門知識

7644 ワード

イベント向けプログラミング(イベント駆動プログラミング):
プログラム中のすべてのプログラムは、イベントによって決定する、Cは、ユーザによって操作(キーボード、マウス)されてもよいし、他のプログラムやストリームの到着や、ネットワークパケットの到着などのオペレーティングシステムイベントによって実行をトリガするもよい.
イベント向けプログラミングは、コンピュータプログラムを書き、その中のコード(通常のプログラムの機能のヘッダ)がアプリケーションの主回路を明確に割り当てられ、そのコード自体がイベントとイベント処理のコードの2つの部分からなる方法として定義することもできる.
イベント向けのプログラミングは、通常、3つの場合に適用されます.
1.ユーザインタフェースの制御(グラフィックを含む)2を作成する.サーバベースのアプリケーション3を作成する.ゲームプログラミング時の複数のオブジェクトの管理
我々のシステム管理では、このようなアプリケーションは、サーバアプリケーションが10000個の同時接続(いわゆるC 10 k問題)を解決するために使用されるイベント向けのプログラミングを多く使用しています.
AnyEventは非常に性能の良いイベントベースのプログラムで、C 10 kの問題を解決するために使用されている人がいます.普段私たちが書いたプログラムのように、プロセスベースです.私たちはまず事件をやり終えます1->それから事件をします2->それから事件をします3.この方式
しかし、イベントベースは全く異なり、主流のプロセスでは基本的に1つの主体フレームワークしかなく、プログラムの動作トリガはイベントによって駆動されます.例えば私たちが使っているウィンドウプログラムです.ポイント最大化の最小化は、すべてイベントに基づいて、最大化イベントを受信して最大化イベントの部分を行うプログラムが実行を開始する.最初から最後まで実行しない.だから私たちは事件に基づくプログラムを読んで、思考の導図を描いて私たちの理解を助けたほうがいいです.
イベントベースのプログラムでよく使われる最大のメリットは、非同期化に使用することです.例えば、100個のファイルをダウンロードし、ダウンロード後にこれらのファイルを処理することです.ダウンロードおよび処理の各プロセスはイベントとして作成することができ、これらのイベントは同期して実行することができる(重要なのは、ネットワーク接続およびファイルの読み書きIOを行う際に待機し、イベントはこれらの待機を多重化することである).Perlのselectという機能を知っているかどうかはわかりませんが、ハンドルが読めるか書くかを待って、異なる読み書きの操作をします.イベントループも同じです.
AnyEventの入門全体では、WATCHERS(モニタ)と条件変数の2つの点に注目すればよい.
WATCHERS(モニタ)
selectでは、「モニタ」という役割があります.select関数自体です.AnyEventではIOだけでなく他のイベントも監視できる.違う処理をする.あることをじっと見つめている人の中には、次のような基本的なものが内蔵されていると見ることができます(「監視者」).TIMER:監視時間、一定の条件に達して、それから異なる時間に対して異なるイベントI/Oをする:これはIOが読み書きできるかどうかを監視して、それから相応のイベントIDLEをする:暇な時どんなイベントSIGNALをする:監視観は異なった情報を調べて、相応の事件CHILD PROCESSを呼び出す:サブルーチンの状態に対して相応の処理イベントを呼び出す
TIMER WATCHERS
基本構文
 
  
AnyEvent->timer(
after => $seconds, # .
interval => $seconds, # , callback.
cb => $cb, # cb callback , , , cb => .
);

使用例:
以下の例は、5秒後、2秒毎にcallback中のイベントが、$wという登録されたイベントがundefされるまで(すなわち、$count>10回)行われる.この中のundef$wはこのwatcherをキャンセルする方法です.
 
  
#!/usr/bin/perl
use strict;
use AnyEvent;

my $cv = AnyEvent->condvar;

my $count = 0;
my $w; $w = AnyEvent->timer(
after => 5,
interval => 2,
cb => sub {
$count++;
warn " $count ";
if ($count >= 10) {
undef $w;
}
}
);
$cv->recv;

I/O WATCHERS
基本構文
 
  
my $fh = ....; #

my $io; $io = AnyEvent->io(
fh => $fh, # ,
poll => "w", # r w IO
cb => sub {
syswrite( $fh, " " );
undef $io;
}
);

使用例:
次の例は、ioモニタを用いる読み取り可能にする、cbの関数を呼び出し、ファイルtestを直接読み出す.txtは、1バイトごとに、このファイルを読み終わるまでundefによってこのイベントを消去する.
 
  
#!/usr/bin/perl
use strict;
use AnyEvent;

my $cv = AnyEvent->condvar;

open my $fh, " my $io; $io = AnyEvent->io(
fh => $fh,
poll => "r",
cb => sub {
my $len = sysread( $fh, my $buf, 1 );
if ($len > 0) {
print "read '$buf'
";
}
else {
undef $io;
die " : $!";
}
});

$cv->recv;

IDLE WATCHERS
基本構文
 
  
my $w = AnyEvent->idle (cb => sub { ... });

使用例:
次の例では、プログラム全体で他のイベントが実行する場合にidleが実行される.他のイベントが待機しているときに呼び出されます.
 
  
#!/usr/bin/perl
use strict;
use AnyEvent;

my $cv = AnyEvent->condvar;

my $t; $t = AnyEvent->timer(
after => 1,
interval => 1,
cb => sub { print time()."
" }
);

my $w; $w = AnyEvent->idle(
cb => sub {
warn "idle";
# undef $w;
}
);

$cv->recv;

SIGNAL WATCHERS
基本構文は、POSIX signalを受信と、callback中のイベントを実行することである.
 
  
my $w = AnyEvent->signal (signal => "TERM", cb => sub { ... });

CHILD PROCRSS WATCHERS
基本文法は次の通りです.
 
  
# child process exit
my $w = AnyEvent->child (pid => $pid, cb => sub {
my ($pid, $status) = @_;
...
});

条件変数(複数条件の場合)
これはAnyEventが上記のいくつかのイベントの監視を学んだ後に理解しなければならないことです.上にAnyEvent->condvarがあるのを見ました$cv->recvの2つと、condvarはcondition variableの略です.どのような条件が成立したときの変数ですか
実は条件であり、どのような条件に達するとイベントループを終了する.だからAnyEventには伝統的なイベントのloop関数はありません.したがって、条件変数を用いることは、イベントを回転させることに相当する.
基本的な$cv->recvは$cv->sendとペアで現れ、イベントがsendを呼び出すと、イベントを終了するにはrecvがこの呼び出しを受信する必要があります.
次の$cv->beginと$cv->endも基本的にこの意味です.sendは単一の条件である.beginとendは複数の条件が成立すると脱退するが、言い換えれば、これらのイベントがペアで完了した後、イベントを脱退する.
 
  
#!/usr/bin/perl
use strict;
use AnyEvent;

my $cv = AnyEvent->condvar( cb => sub {
warn " ";
});

for my $i (1..10) {
$cv->begin;
my $w; $w = AnyEvent->timer(after => $i, cb => sub {
warn "finished timer $i";
undef $w;
$cv->end;
});
}

$cv->recv;

デフォルトのcondvarはイベントに偽の変数を設定するので、sendやbegin sendなどが直接本物になり、イベントループを終了します.この場所を一つの信号量として理解すればよい.y条件が成立しなければ、AnyEventではイベントはずっとloopする.上記の例ではsendはありません
AnyEventについては、入門後にAnyEvent::HTTP、twiggyなどを遊ぶことができます.これらのアプリケーションとプロジェクトを見てください.
また、AnyEventではEVをよく使用する.彼はCのlibevのPerlインタフェースで、非常に高い性能を持っています.上を見終わって、下のEVの使用を見て、とても簡単でしょう、基本的に変わらない.ただ条件変数が現れず、従来のEV::loop;これを実行します.
 
  
use EV;

# TIMERS

my $w = EV::timer 2, 0, sub {
warn "is called after 2s";
};

my $w = EV::timer 2, 2, sub {
warn "is called roughly every 2s (repeat = 2)";
};

undef $w; # destroy event watcher again

my $w = EV::periodic 0, 60, 0, sub {
warn "is called every minute, on the minute, exactly";
};

# IO

my $w = EV::io *STDIN, EV::READ, sub {
my ($w, $revents) = @_; # all callbacks receive the watcher and event mask
warn "stdin is readable, you entered: ", ;
};

# SIGNALS

my $w = EV::signal 'QUIT', sub {
warn "sigquit received
";
};

# CHILD/PID STATUS CHANGES

my $w = EV::child 666, 0, sub {
my ($w, $revents) = @_;
my $status = $w->rstatus;
};

# STAT CHANGES
my $w = EV::stat "/etc/passwd", 10, sub {
my ($w, $revents) = @_;
warn $w->path, " has changed somehow.
";
};

# MAINLOOP
EV::loop; # loop until EV::unloop is called or all watchers stop
EV::loop EV::LOOP_ONESHOT; # block until at least one event could be handled
EV::loop EV::LOOP_NONBLOCK; # try to handle same events, but do not block

注:本文の大部分は日本の@lestrrat