面试中常被问到的(20)select,poll,epoll对比
Posted AllenSquirrel
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面试中常被问到的(20)select,poll,epoll对比相关的知识,希望对你有一定的参考价值。
从以下四个角度进行对比:
- 用户态将文件描述符传入内核的方式
(1)select:创建三个文件描述符集并拷贝到内核中,分别监听 读,写,异常动作
(2)poll:将传入struct pollfd结构体数组(包含需要监控的描述符及对应事件以及返回实际就绪事件)拷贝到内核中
(3)epoll:调用epoll_create接口,在内核缓冲区中建立一棵红黑树以及双链表,向内核中添加需要监控的文件描述符,在红黑树增加对应节点
- 内核态检测文件描述符读写状态的方式
(1)select:采用轮询遍历,遍历所有文件描述符fd,找到读写操作就绪状态的描述符
(2)poll:采用轮询遍历,查询每一个fd状态,如果就绪则在等待队列中加入一项继续遍历
(3)epoll:采用回调机制,执行add操作将文件描述符放到红黑树上,而且注册回调函数,内核在检测到某文件描述符可读,可写时会调用回调函数,通过回调函数将文件描述符添加到就绪双向链表中
- 找到就绪文件描述符并传递给用户态的方式
(1)select:将描述符状态集合拷贝到内核,并返回就绪的文件描述符总数。用户态需要遍历来判断哪些文件描述符处于就绪态
(2)poll:将struct pollfd结构体数组拷贝到内核,并返回就绪的文件描述符总数
(3)epoll:调用epoll_wait监控就绪链表中有无数据,最后将链表的数据返回给数组并返回就绪描述符总数。内核将就绪的文件描述符放在传入数组中,数组中都是已经就绪的事件只用遍历依次处理即可
- 重复监听的处理方式
(1)select:将新的监听文件描述符集合拷贝传入内核,继续以上步骤
(2)poll:将新的struct pollfd结构体数组拷贝传入内核,继续以上步骤
(3)epoll:无需重建红黑树,沿用即可
epoll高效的原因:
- select和poll动作基本一致,poll采用结构体数组进行文件描述符存储,select采用fd二进制标注位来存储,所以select会受到最大监控描述符数上限,而poll和epoll都不会受限
- select,poll,epoll都会返回就绪描述符数量,但是select和poll都不会具体明确指出是那些描述符就绪,需要遍历判断,而epoll直接返回就绪描述符数组,直接处理即可
- select和poll都需要将文件描述符集合或结构体数组拷贝进内核监听完成再从中拷贝出来,而epoll中描述符以及事件结构只需要向内核拷贝一次(通过epoll_event保存返回)实现内核中消息传递,减少复制开销
- select,poll均采用轮询方式来检测事件是否处于就绪态,而epoll采用回调机制,随着fd描述符增加,select和poll效率受影响,而epoll影响不大
- epoll边缘触发机制,效率高。若某个描述符有数据接收到,但数据不完整,如果使用水平触发,只要不从缓冲区取空所有数据则一直触发事件,而边缘触发只有新数据到来才会触发事件,查看数据是否完整,有效避免一种事件由于数据不完整不想处理但一直被不断触发的情况。
以上是关于面试中常被问到的(20)select,poll,epoll对比的主要内容,如果未能解决你的问题,请参考以下文章