Libevent(一)

一、什么是libevent

libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue、IOCP等系统调用管理事件机制。著名分布式缓存软件memcached也是基于libevent,而且libevent在使用上可以做到跨平台,而且根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。——引用自百度百科

需要注意以下几点:

  1. libevent是一个事件触发的网络库
  2. 可以跨平台(windows、linux、bsd等)
  3. 使用select、epoll(linux)、kqueue(freebsd)、IOCP(windows)等系统调用管理事件机制(IO复用)
  4. libevent在Linux环境下默认采用epoll作为IO多路复用方法

用户线程使用libevent则通常按以下步骤:

  1. 用户线程通过event_init()函数创建一个event_base对象。event_base对象管理所有注册到自己内部的IO事件。多线程环境下,event_base对象不能被多个线程共享,即一个event_base对象只能对应一个线程。
  2. 然后该线程通过event_add函数,将与自己感兴趣的文件描述符相关的IO事件,注册到event_base对象,同时指定事件发生时所要调用的事件处理函数(event handler)。服务器程序通常监听套接字(socket)的可读事件。比如,服务器线程注册套接字sock1的EV_READ事件,并指定event_handler1()为该事件的回调函数。libevent将IO事件封装成struct event类型对象,事件类型用EV_READ/EV_WRITE等常量标志。
  3. 注册完事件之后,线程调用event_base_loop进入循环监听(monitor)状态。该循环内部会调用epoll等IO复用函数进入阻塞状态,直到描述符上发生自己感兴趣的事件。此时,线程会调用事先指定的回调函数处理该事件。例如,当套接字sock1发生可读事件,即sock1的内核buff中已有可读数据时,被阻塞的线程立即返回(wake up)并调用event_handler1()函数来处理该次事件。
  4. 处理完这次监听获得的事件后,线程再次进入阻塞状态并监听,直到下次事件发生。

—— 引用自Memcached网络模型

二、php使用libevent扩展实现高性能服务器

此处不再赘述php-libevent扩展的安装。
上述在描述libevent步骤时候,用的并非php函数,php实现是略微有区别,大致流程不变。

在之前的文章『php-socket 实现简单服务器』中,我们使用stream+select的方式来实现一个简单的服务器。

现在我们就使用libevnet来实现更高性能的服务器。

附上libevent的常量