1、select: select库是在linux和windows平台都基本支持的 事件驱动模型库,并且在接口的定义也基本相同,只是部分参 数的含义略有差异,最大并发限制1024,是最早期的事件驱动模型。
2、poll: 在Linux 的基本驱动模型,windows不支持此驱动模型,是select的升级版,取消了最大的并发限制,在编译 nginx的时候可以使用--with-poll_module和--without-poll_module这两个指定是否编译select库。
3、epoll: epoll是库是Nginx服务器支持的最高性能的事件驱动库之一,是公认的非常优秀的事件驱动模型,它和select 和poll有很大的区别,epoll是poll的升级版,但是与poll的效率有很大的区别. epoll的处理方式是创建一个待处理的事件列表,然后把这个列表发给内核,返回的时候在去轮训检查这个表,以 判断事件是否发生,epoll支持一个进程打开的最大事件描述符的上限是系统可以打开的文件的最大数,同时 epoll库的IO效率不随描述符数目增加而线性下降,因为它只会对内核上报的“活跃”的描述符进行操作。
Select: POSIX所规定,目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,本质上是通过设置或者检查存 放fd标志位的数据结构来进行下一步处理 缺点 单个进程能够监视的文件描述符的数量存在最大限制,在Linux上一般为1024,可以通过修改宏定义 FD_SETSIZE,再重新编译内核实现,但是这样也会造成效率的降低 单个进程可监视的fd数量被限制,默认是1024,修改此值需要重新编译内核 对socket是线性扫描,即采用轮询的方法,效率较低 select 采取了内存拷贝方法来实现内核将 FD 消息通知给用户空间,这样一个用来存放大量fd的数据结构,这样 会使得用户空间和内核空间在传递该结构时复制开销大
poll: 本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态 其没有最大连接数的限制,原因是它是基于链表来存储的 大量的fd的数组被整体复制于用户态和内核地址空间之间,而不管这样的复制是不是有意义 poll特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd
在Linux 2.6内核中提出的select和poll的增强版本 支持水平触发LT和边缘触发ET,最大的特点在于边缘触发,它只告诉进程哪些fd刚刚变为就需态,并且只会通知一 次 使用“事件”的就绪通知方式,通过epoll_ctl注册fd,一旦该fd就绪,内核就会采用类似callback的回调机制来 激活该fd,epoll_wait便可以收到通知 优点: 没有最大并发连接的限制:能打开的FD的上限远大于1024(1G的内存能监听约10万个端口),具体查 看/proc/sys/fs/file-max,此值和系统内存大小相关 效率提升:非轮询的方式,不会随着FD数目的增加而效率下降;只有活跃可用的FD才会调用callback函数,即 epoll最大的优点就在于它只管理“活跃”的连接,而跟连接总数无关 内存拷贝,利用mmap(Memory Mapping)加速与内核空间的消息传递;即epoll使用mmap减少复制开销