select,poll和epoll特点和区别

工作流程

1.poll和select的工作流程
poll本质上和select没有区别,它将用户传入的数组拷贝到内核空间,然后查询每个fd对应的设备状态,如果设备就绪则在设备等待队列中加入一项并继续遍历,如果遍历完所有fd后没有发现就绪设备,则挂起当前进程,直到设备就绪或者主动超时,被唤醒后它又要再次遍历fd。这个过程经历了多次无谓的遍历。

2.epoll的工作流程
在这里插入图片描述
1.通过调用 epoll_create() 函数创建并初始化一个 eventpoll 对象。
2.通过调用 epoll_ctl() 函数把被监听的文件句柄 (如socket句柄) 封装成 epitem 对象并且添加到 eventpoll 对象的红黑树中进行管理。
3.通过调用 epoll_wait() 函数等待被监听的文件状态发生改变。
4.当被监听的文件状态发生改变时(如socket接收到数据),会把文件句柄对应 epitem 对象添加到 eventpoll 对象的就绪队列 rdllist 中。并且把就绪队列的文件列表复制到 epoll_wait() 函数的 events 参数中。
5.唤醒调用 epoll_wait() 函数被阻塞(睡眠)的进程。

epoll工作方式用更通俗的话描述就是:epoll_ctl() 用于向内核注册新的描述符或者是改变某个文件描述符的状态。已注册的描述符在内核中会被维护在一棵红黑树上,通过回调函数内核会将 I/O 准备好的描述符加入到一个链表中管理,进程调用 epoll_wait() 便可以得到事件完成的描述符。

各自的特点

  • select使用数组来存储fd。
    移植性最好。

  • poll使用链表来存储fd。
    poll有一个特点是“水平触发”,如果报告了fd后,没有被处理,那么下次poll时会再次报告该fd。

  • epoll 的描述符事件有两种触发模式:LT(level trigger)和 ET(edge trigger)。
    LT: 当 epoll_wait() 检测到描述符事件到达时,将此事件通知进程,进程可以不立即处理该事件,下次调用 epoll_wait() 会再次通知进程。是默认的一种模式.
    ET:和 LT 模式不同的是,通知之后进程必须立即处理事件,除非有新的数据流入,下次再调用 epoll_wait() 时不会再得到事件到达的通知,.很大程度上减少了 epoll 事件被重复触发的次数,因此效率要比 LT 模式高

poll和select的区别

  • select 会修改描述符,而 poll 不会;
  • select 的描述符类型使用数组实现,FD_SETSIZE 大小默认为 1024,因此默认只能监听少于 1024 个描述符。如果要监听更多描述符的话,需要修改 FD_SETSIZE 之后重新编译;而 poll使用链表实现,没有描述符数量的限制;
  • poll 提供了更多的事件类型,并且对描述符的重复利用上比 select 高。

三者区别

1.支持一个进程所能打开的最大连接数

selectpollepoll
单个进程所能打开的最大连接数有FD_SETSIZE宏定义,其大小是默认是1024,当然我们可以对进行修改,然后重新编译内核,但是性能可能会受到影响,这需要进一步的测试。没有最大连接数的限制,原因是它是基于链表来存储的虽然连接数有上限,但是很大,1G内存的机器上可以打开10万左右的连接,2G内存的机器可以打开20万左右的连接

2. FD剧增后带来的IO效率问题

selectpollepoll
因为每次调用时都会对连接进行线性遍历,查找准备好的描述符,所以随着FD的增加会造成遍历速度慢的“线性下降性能问题”。同左因为epoll内核中实现是根据每个fd上的callback函数来实现的,只有活跃的socket才会主动调用callback,所以在活跃socket较少的情况下,使用epoll没有前面两者的线性下降的性能问题,但是所有socket都很活跃的情况下,可能会有性能问题。

3.消息传递方式

selectpollepoll
内核需要将消息传递到用户空间,都需要内核拷贝动作同左epoll通过内核和用户空间共享一块内存来实现的。

参考资料

https://cloud.tencent.com/developer/article/1685663
https://blog.csdn.net/qq_45980600/article/details/104854434
https://github.com/CyC2018/CS-Notes/blob/master/notes/Socket.md#epoll

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值