事件驱动模型
事件驱动模型一般是由事件收集器、事件发送器和事件处理器三部分组成基本单元组成。
一、select库
select库是各个版本的linux和windows平台都支持的基本事件驱动模型库,并且在接口的定义上也基本相同,只是部分参数的含义略有差异。
使用select库的一般步骤:创建所关注事件的描述集合。对于一个描述符,可以关注其上面的读事件、写事件以及异常发生事件,所以要创建三类事件描述符集合,分别用来收集读事件的描述符、写事件的描述符和异常事件的描述符。
其次,调用底层提供的select()函数,等待事件的发生。select的阻塞与是否设置非阻塞的IO是没有关系的。
然后,轮询所有事件描述符集合中的每一个事件描述符,检查是否有响应的时间发生,如果有,则进行处理。
nginx服务器在编译过程中如果没有为其指定其他高性能事件驱动模型库,它将自动编译该库。
可以使用--with-select_module和--without-select_module两个参数,强制nginx是否编译该库。
二、poll库
poll库,作为linux平台上的基本事件驱动模型,Windows平台不支持poll库。
使用poll库的一般过程是:与select的基本工作方式是相同的,都是先创建一个关注事件的描述符集合,再去等待这些事件的发生,然后在轮询描述符集合,检查有没有事件发生,如果有,就进行处理。
与select的主要区别是select需要为读事件、写事件、异常事件分别创建一个描述符的集合,因此在轮询的时候,需要分别轮询这三个集合。而poll库只需创建一个集合,在每个描述符对应的结构上分别设置读事件,写事件和异常事件,最后轮询的时候可以同时检查这三种事件是否发生。是select库优化的实现。
nginx服务器在编译过程中如果没有为其指定其他高性能事件驱动模型库,它将自动编译该库。
可以使用--with-poll_module和--without-poll_module两个参数,强制nginx是否编译该库。
三、epoll库
epoll库是Nginx服务器支持的高性能事件之一,它是公认的非常优秀的时间驱动模型,和poll和select有很大的不同,属于poll库的一个变种,他们的处理方式都是创建一个待处理事件列表,然后把这个事件列表发送给内核,返回的时候,再去轮询检查这个列表,以判断事件是否发生。如果这样的描述符在比较多的应用中,效率就显得低下了,epoll是描述符列表的管理交给内核负责,一旦某种事件发生,内核会把发生事件的描述符列表通知给进程,这样就避免了轮询整个描述符列表,epoll库得到事件列表,就开始进行事件处理了。
四、其他事件驱动模型
kqueue模型 用于FreeBSD 4.1及以上版本 OpenBSD2.9、NetBSD2.0及Mac os X平台上。都是通过避免轮询操作提供效率。该模型同时支持条件触发(也叫水平触发,只要满足条件就触发一个事件)和边缘触发(每个状态变化时,就触发一个事件)
/dev/poll 主要用在unix衍生平台的高效事件驱动模型,主要在solaris7 11/99及以上版本 HP/UX11.22以上版本等
eventport 模型,用于支持solaris 10及以上版本平台的高效事件驱动模型。