select、poll、epoll

  • Post author:
  • Post category:其他


SELECT

fd_set 使用数组实现

1.fd_size 有限制 1024 bitmap

fd【i】 = accept()

2.fdset不可重用,新的fd进来,重新创建

3.用户态和内核态拷贝产生开销

4.O(n)时间复杂度的轮询

5.成功调用返回结果大于 0,出错返回结果为 -1,超时返回结果为 0;具有超时时间

POLL

基于结构体存储fd

struct pollfd{


int fd;

short events;

short revents; //可重用

}

解决了select的1,2两点缺点

EPOLL

解决select的1,2,3,4

不需要轮询,时间复杂度为O(1)

epoll_create 创建一个白板 存放fd_events

epoll_ctl 用于向内核注册新的描述符或者是改变某个文件描述符的状态。已注册的描述符在内核中会被维护在一棵红黑树上

epoll_wait 通过回调函数内核会将 I/O 准备好的描述符加入到一个链表中管理,进程调用 epoll_wait() 便可以得到事件完成的描述符

两种触发模式:

LT:水平触发

当 epoll_wait() 检测到描述符事件到达时,将此事件通知进程,进程可以不立即处理该事件,下次调用 epoll_wait() 会再次通知进程。是默认的一种模式,并且同时支持 Blocking 和 No-Blocking。

ET:边缘触发

和 LT 模式不同的是,通知之后进程必须立即处理事件。

下次再调用 epoll_wait() 时不会再得到事件到达的通知。很大程度上减少了 epoll 事件被重复触发的次数,

因此效率要比 LT 模式高。只支持 No-Blocking,以避免由于一个文件句柄的阻塞读/阻塞写操作把处理多个文件描述符的任务饿死



版权声明:本文为m0_38093304原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。