Perl AnyEvent中的watcher实例
这几天看了下perl的事件编程框架AnyEvent,重点参考了一下几篇文章:
http://search.cpan.org/~mlehmann/AnyEvent-7.05/lib/AnyEvent.pm
http://search.cpan.org/~mlehmann/AnyEvent-7.05/lib/AnyEvent/Intro.pod
https://www.nhooo.com/article/55278.htm
1、什么是事件编程?
举个简单的例子,你浏览网页的时候,你点击一个图片,蹭的弹出一个东西,你不点,那就在那里,等待一个人来点它。如果你写过js,其实就是,你注册了很多的时间比如click,dbclick,keybord,submit等,那么浏览器就起到帮我们去监听这些事件的发生(Loop)。当有对应的事件发生的时候,我们也一般也设置了callback,比如onclick,onsubmit等,去响应这些事件,这基本就是事件编程的一个缩影了。
2、perlAnyEvent中的watcher
在AnyEvent中有5中watcher,分别是IO,timer,signal,child,idle.
2.1iowatcher
#!/usr/bin/perl
useAnyEvent;
my$cv=AnyEvent->condvar;
#openmy$file,'<','test.txt'ordie"$!";
openF,'<','test.txt'ordie"$!";
my$io_watcher=AnyEvent->io(
fh =>*F,
poll=>'r',
cb =>sub{
chomp(my$input=sysreadF,my$buf,1024);#readaline
warn"read:$buf\n" if$input>0; #outputwhathasbeenread
#$cv->sendif/quit/;#quitprogramif/quit/i
},
);
$cv->recv;#waituntiluserenters/quit/i
timerwatcher
AnyEvent的timer的一部分其实像javascript的setInterval:
#!/usr/bin/perl
use5.016;
useAnyEvent;
my$cv=AnyEvent->condvar;
my$w=AnyEvent->timer(
after=>0, #多少秒之后触发事件
interval=>2, #多少秒触发事件
cb=>sub{
sayAnyEvent->time,"",AnyEvent->now;
}
);
$cv->recv;
signalwatcher
前面我们在的文章中写到了perl中对于信号的处理《perl信号处理简单学习》,这里主要是AnyEvent中对于这些事件的处理。
#!/usr/bin/perl
use5.016;
useAnyEvent;
#sayforkeys%SIG;看一下又多少信号
my$cv=AnyEvent->condvar;
my$w=AnyEvent->signal(
signal=>'INT',
cb=>sub{
sayAnyEvent->time,"",AnyEvent->now;
exit1;
}
);
$cv->recv;
childwatcher
#!/usr/bin/perl
useAnyEvent;
my$done=AnyEvent->condvar;
my$pid=forkorexit5;
my$w=AnyEvent->child(
pid=>$pid,
cb =>sub{
my($pid,$status)=@_;
warn"pid$pidexitedwithstatus$status";
$done->send;
},
);
#dosomethingelse,thenwaitforprocessexit
$done->recv;
idlewatcher
就是如果mainloop在空闲的时候做些什么呢?
#!/usr/bin/perl
useAnyEvent;
my@lines;#readdata
my$idle_w;
$cv=AnyEvent->condvar;
my$io_w=AnyEvent->io(fh=>\*STDIN,poll=>'r',cb=>sub{
push@lines,scalar<STDIN>;
#startanidlewatcher,ifnotalreadydone
$idle_w||=AnyEvent->idle(cb=>sub{
#handleonlyoneline,whentherearelinesleft
if(my$line=shift@lines){
print"handledwhenidle:$line";
}else{
#otherwisedisabletheidlewatcheragain
undef$idle_w;
}
});
});
$cv->recv;