perl AnyEvent简单介绍和入门知识

什么是面向事件的编程(事件驱动的编程):

编程中所有的程序是由事件决定 – 可以是由用户操作(键盘,鼠标),也可以是由其他程序和流的到达或者操作系统事件(如网络数据包到达)来触发执行.

面向事件编程可以也被定义为,写一个计算机程序,在其中的代码(通常程序的功能的头部)被明确分配应用程序的主回路,其代码本身由两部分组成方法:事件和事件处理的代码。

面向事件的编程通常被应用在三种情况下:

1.创建用户界面的控制(包括图形)
2.创建一个基于服务器的应用程序
3.游戏编程时多个对象的管理

我们系统管理时,这种应用在服务器的应用程序中使用面向事件的编程很多,比如用于服务器应用解决10,000个并发连接(所谓 C10k 问题)

AnyEvent 是一个性能非常好的基于事件驱动的程序,有人使用它来解决 C10k 的问题,象平时我们写的程序,都是基于过程.我们都是先做完事件1-> 然后做事件2->然后做事件3 .这种方式.

但基于事件就完全不一样了,在主流程中你基本只有一个主体框架,程序的动作触发都是由事件来驱动.比如我们使用的窗口程序.点最大化最小化,都是基于事件,当接收到了最大化的事件做最大化事件那部分的程序开始运行.不在从头到尾部来执行.所以我们读基于事件的程序,最好是画成思维导图来帮助我们理解.

基于事件的程序常用到的最大好处是用来做异步,例如,我们要下载 100 个文件,下载完后对这些文件进行处理.可能给每个下载和处理的过程写成事件,这些事件可以同步运行(关键在于网络连接和进行文件的读写 IO 时要等待,事件是给这些等待复用起来).
不知大家了解 Perl 中的 select 这个功能不,就是等到句柄可以读或者写的时候,做不同的读或者写的操作.事件循环也是一样.

在整个 AnyEvent 入门中,我们只要关注二个点就行, WATCHERS(监控者) 和 条件变量.

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,每次一个字节,直到读完这个文件就通过 undef 消掉这个事件.

代码如下:

#!/usr/bin/perl
use strict;
use AnyEvent;

my $cv = AnyEvent->condvar;

open my $fh, "<test.txt" or die "不能打开文件句柄 $!";
my $io; $io = AnyEvent->io(
fh => $fh,
poll => "r",
cb => sub {
my $len = sysread( $fh, my $buf, 1 );
if ($len > 0) {
print "read '$buf'\n";
}
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()."\n" }
);

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这二个,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: ", <STDIN>;
};

# SIGNALS

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

# 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.\n";
};

# 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

(0)

相关推荐

  • perl AnyEvent简单介绍和入门知识

    什么是面向事件的编程(事件驱动的编程): 编程中所有的程序是由事件决定 – 可以是由用户操作(键盘,鼠标),也可以是由其他程序和流的到达或者操作系统事件(如网络数据包到达)来触发执行. 面向事件编程可以也被定义为,写一个计算机程序,在其中的代码(通常程序的功能的头部)被明确分配应用程序的主回路,其代码本身由两部分组成方法:事件和事件处理的代码. 面向事件的编程通常被应用在三种情况下: 1.创建用户界面的控制(包括图形) 2.创建一个基于服务器的应用程序 3.游戏编程时多个对象的管理 我们系统管理

  • Java框架入门之简单介绍SpringBoot框架

    前言 Spring都包含了哪些部分呢? 主要包含Spring Boot.Spring Framework.Spring Data.Spring Cloud.Spring Cloud Data Flow.Spring Security.Spring Batch等众多项目.在spring的官网中对其有详细的介绍. 一.SpringBoot是什么? SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,

  • perl运算符使用介绍与简单应用

    perl 5基础教程--运算符 一.算术运算符 :+(加).-(减).*(乘)./(除).**(乘幂).%(取余).-(单目负) (1)乘幂的基数不能为负,如 (-5) ** 2.5 # error:  (2)乘幂结果不能超出计算机表示的限制,如10 ** 999999 # error  (3)取余的操作数如不是整数,四舍五入成整数后运算:运算符右侧不能为零  (4)单目负可用于变量: - $y ; # 等效于 $y * -1  (5)对应有 +=.-=.*=./=.**=.%= 二.整数比较运

  • MySQL基础快速入门知识总结(附思维导图)

    目录 前言 一.数据库基础知识 1.什么是数据库 2.数据库的分类 3.数据库的常用语言 4.数据库的常用操作方式 5.MySQL的架构 二.数据库的增删改查 1.创建数据库 2.查询数据库 3.修改数据库 4.删除数据库 三.表的增删改查 1.创建表 2.查询表 3.修改表 4.删除表 四.记录的增删改查 1.插入记录 2.查询记录(最常用) 3.修改记录 4.删除记录 五.字段类型 1.数字型 1.1整数型 1.2小数型 2.文本型 3.日期时间 六.字段属性 总结 前言 本文是我这段时间自

  • 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 http://www.jb51.net/article/55278.htm 1.什么是事件编程? 举个简单的例子,你浏览网页的时候,你点击一个图片,蹭的弹出

  • json简单介绍

    JSON简单介绍: 所谓的JSON是JavaScript Object Notation的缩写,意思是javascript对象表示法. 下面对JSON做一下总结: (1).JSON指的是javascript对象表示法,是JavaScript Object Notation的缩写. (2).JSON是轻量级的文本数据交换格式. (3).JSON是独立于平台和语言的. (4).JSON是具有自我描述性,非常易于理解. 特别说明:JSON是一种用来规范字符串数据格式的语法. 代码实例: 实例一: {"

  • Apache shiro的简单介绍与使用教程(与spring整合使用)

    apache shiro框架简介 Apache Shiro是一个强大而灵活的开源安全框架,它能够干净利落地处理身份认证,授权,企业会话管理和加密.现在,使用Apache Shiro的人越来越多,因为它相当简单,相比比Spring Security,Shiro可能没有Spring Security那么多强大的功能,但是在实际工作时可能并不需要那么复杂的东西,所以使用简单的Shiro就足够了. 以下是你可以用 Apache Shiro所做的事情: Shiro的4大核心部分--身份验证,授权,会话管理

  • 构造函数中Perl方法用法介绍

    Perl语言中Perl方法的概念你是否了解,这里向大家简单介绍一下,Perl类的Perl方法只不过是一个Perl子程序而已,也即通常所说的成员函数. Perl方法 一.Perl方法简介 Perl类的Perl方法只不过是一个Perl子程序而已,也即通常所说的成员函数.Perl方法定义不提供任何特殊语法,但规定Perl方法的第一个参数为对象或其被引用的包.Perl有两种Perl方法:静态Perl方法和虚Perl方法.静态Perl方法第一个参数为类名,虚Perl方法第一个参数为对象的引用.Perl方法

  • JS操作时间 - UNIX时间戳的简单介绍(必看篇)

    准备知识 GMT(Greenwich Mean Time) - 格林尼治时间.UTC(Universal Time Code) - 国际协调时间.PST(Pacific Standard Time,太平洋标准时间). UTC出现的比GMT时间晚,可以认为UTC时间更加精确,不过它们之间只相差几秒钟. UTC开始时间为:1970-01-01T00:00:00.000Z(这种时间设置可以一直精确到毫秒,字母T和Z仅仅是一种格式) UNIX时间戳指的是从1970-01-01T00:00:00.000Z

  • 简单介绍Java垃圾回收机制

    Java的内存分配与回收全部由JVM垃圾回收进程自动完成.与C语言不同,Java开发者不需要自己编写代码实现垃圾回收.这是Java深受大家欢迎的众多特性之一,能够帮助程序员更好地编写Java程序. 这篇教程是系列第一部分.首先会解释基本的术语,比如JDK.JVM.JRE和HotSpotVM.接着会介绍JVM结构和Java堆内存结构.理解这些基础对于理解后面的垃圾回收知识很重要. Java关键术语 JavaAPI:一系列帮助开发者创建Java应用程序的封装好的库. Java开发工具包(JDK):一

随机推荐