资讯专栏INFORMATION COLUMN

PHP之高性能I/O框架:Libevent(一)

klivitamJ / 2097人阅读

摘要:是一个用语言编写的轻量级的开源高性能框架,支持多种多路复用技术和等支持,定时器和信号等事件注册事件优先级。定时器提供了系列函数,实现一次性定时器,精度微秒。

Libevent 是一个用C语言编写的、轻量级的开源高性能I/O框架,支持多种 I/O 多路复用技术: epoll、 poll、 dev/poll、 select 和 kqueue 等;支持 I/O,定时器和信号等事件;注册事件优先级。PHP提供了对应的扩展 libevent、 Event 。

libevent扩展很久没有更新了,仅支持PHP5系列,PHP7虽然有网友fork了 libevent 扩展的源码进行更新兼容,但是稳定性不好,可能会出现段错误,所以PHP7最好使用 Event 扩展。

与libevent扩展不同的是,Event 扩展提供了面向对象的接口,且支持更多特性。

libevent扩展

libevent地址: http://pecl.php.net/package/l...
libevent文档: http://docs.php.net/libevent

系统需要先安装 Libevent 库:

yum install libevent-dev

然后安装PHP扩展。

PHP5安装:

pecl install libevent-0.1.0

PHP7安装(不稳定):

git clone https://github.com/expressif/pecl-event-libevent.git
cd pecl-event-libevent
phpize
./configure
make && sudo make install

注:后面的代码示例均使用的php5.6 + libevent-0.1.0环境。

基本使用

下面的例子实现了一个单进程的TCP server,基于libevent实现I/O复用,达到高性能。

libevent_tcp_server.php


我们先运行代码:

$ php libevent_tcp_server.php
waiting client...
start run...

客户端使用telnet:

$ telnet 127.0.0.1 9201
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is "^]".
hello server!

代码里面我加了很多注释,基本上能看明白。需要注意的是:
1、event_base是全局的,只需要创建一次,后续都是event的设置和添加。
2、event_set 的回调函数有三个参数,分别是$fd, $events, $arg。也就是 event_set 函数的$fd, $events, $arg参数。arg 如果需要多个,可以为数组。fd参数实际是保存的客户端连接,是个resource。events参数支持下列这些常量:

EV_TIMEOUT: 超时。利用事件可以实现定时器

EV_READ: 只要网络缓冲中还有数据,回调函数就会被触发

EV_WRITE: 只要塞给网络缓冲的数据被写完,回调函数就会被触发

EV_SIGNAL: POSIX信号量

EV_PERSIST: 不指定这个属性的话,回调函数被触发后事件会被删除

EV_ET: Edge-Trigger边缘触发

3、ev_accept 回调里面,后面几行如果不设置,会出现异常。目前没有找到好的解释。
4、ev_read 回调里面,删除客户端连接使用 unset也可以达到同样效果,这个和第3点一样,没有找到好的解释。

使用event_buffer

libevent还提供了event_buffer_系列函数。手册里的解释是:Libevent在基础的API里提供了一层抽象层,使用 buffered event ,我们无序手动处理I/O。估计是对性能的提升。

示例:
libevent_buffer_tcp_server.php


注释我都写了,相比前一个例字,主要有3个地方不同:
1、ev_accept 里设置read事件全换成了待buffer的函数;
2、ev_read 回调接收参数为2个;
3、ev_read 回调里读取消息使用 event_buffer_read,而不是fread。另外增加了ev_writeev_error回调。

定时器

libevent提供了event_timer_*系列函数,实现一次性定时器,精度微秒。

libevent_timer.php

 5){
        event_timer_del($args[1]); //删除定时器
    }
}

$base = event_base_new();
$ev_timer = event_timer_new();
event_timer_set($ev_timer, "ev_timer", [$TIME_INTVAL, $ev_timer]);
event_base_set($ev_timer, $base);
event_timer_add($ev_timer, $TIME_INTVAL);//单位微秒

event_base_loop($base);

上面的例子实现了每1秒执行一次回调函数。

使用event_*系列函数也可以实现:
libevent_timer2.php

 5){
        event_timer_del($args[1]);
    }
}

$base = event_base_new();
$event = event_new();
event_set($event, 0, EV_TIMEOUT, "ev_timer", [$TIME_INTVAL, $event]);
event_base_set($event, $base);
event_add($event, $TIME_INTVAL);

event_base_loop($base);

可以看出,event_timer_*系列函数是对event_*系列函数EV_TIMEOUT事件的包装。

总结

event_*系列函数基本上可以分为上面三大类。还有几个函数没有提到,大家看手册就能了解。

(未完待续)


欢迎关注公众号及时获取最新文章推送!


推荐!每月仅需$2.5,即可拥有配置SSD的VPS!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/28970.html

相关文章

  • 学习笔记Memcached原理

    摘要:而多路复用无需等待任务完成,而是将所有任务维护在一个组中,在等待过程中线程可以去处理其他的任务,当某个任务完成后,再去操作该操作符。而目前仅有的调优方案是调整因子,让的大小尽可能的接近,减少空间的浪费。 0x00 Memcached简述 Memcached是一套高性能的分布式内存对象缓存系统,用于在动态系统中减少数据库负载,提升性能。 0x01 Memcached特性 基于libev...

    imingyu 评论0 收藏0
  • PHP socket初探 --- 颤颤抖抖开篇libevent(

    摘要:原文地址正如标题所言,颤颤抖抖开篇。于是只能是你自己,把单子上的个快递逐次和收到的对比一遍,然后对比完毕后再把这个单子给了阿梅,然后阿梅继续等。剃光头前的阿梅,就是,不敢正眼看老板娘一眼。剃光头后的阿梅,就是,可徒手接魔鬼队的死亡之球。 [原文地址:https://blog.ti-node.com/blog...] 正如标题所言,颤颤抖抖开篇epoll。颤颤抖抖的原因大概也就是以前几乎...

    levinit 评论0 收藏0
  • memcached分布式原理与实现

    摘要:哈希的结果应能够保证原有已分配的内容可以被映射到新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。平衡性平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。 memcached分布式原理与实现 标签(空格分隔): nosql 0x01 概况 1.1 什么是memcached memcached是一个分布式,开源的数据存储引擎。memcach...

    Ververica 评论0 收藏0
  • memcached分布式原理与实现

    摘要:哈希的结果应能够保证原有已分配的内容可以被映射到新的缓冲中去,而不会被映射到旧的缓冲集合中的其他缓冲区。平衡性平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。 memcached分布式原理与实现 标签(空格分隔): nosql 0x01 概况 1.1 什么是memcached memcached是一个分布式,开源的数据存储引擎。memcach...

    LiuRhoRamen 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<