I/O复用:select、poll、epoll区别

select 和poll的区别:

select:

select的触发方式是水平触发(LT),应用程序如果没有完成对一个已经就绪的文件描述符进行IO操作,那么之后每次select调用还是会将这些文件描述符通知进程。

创建数组,保存描述符

(一次while要做的事:)

  1. 清空集合FD_ZERO
  2. 遍历数组,将fd写入fdset集合中(由于内核对fd_set的修改,应用程序下次调用select前需要重置fd_set集合。),循环次数由描述符个数决定
  3. 将fdset集合传给select(系统调用)---->从用户空间向内核空间拷贝(select需要复制大量的句柄数据结构,产生巨大的开销);
  4. 内核实现是轮询方式(一个一个检查,检测那些事件就绪),将其中就绪的描述符返回给应用程序,检测就绪事件的算法的时间复杂度为o(n),描述符越多,耗时越长,性能越差
  5. select返回后,需遍历所有描述符,找到就绪的描述符(FD_ISSET)

相比select模型,poll使用链表保存文件描述符,因此没有了监视文件数量的限制

poll:

 poll通过把文件描述符和事件定义在pollfd中,任何事件都被统一处理,从而使得编程接口简洁许多。并且内核每次修改的是pollfd结构体的revents成员,而events成员保持不变,因此下次调用poll时无须重置pollfd结构体类型的事件集参数。

  1. 不需要每次清空数组,只要需要动态维护住即可
  2. 将数组传给Poll(系统调用)---->从用户空间向内核空间拷贝
  3. 内核实现是轮询方式(一个一个检查),将其中就绪的描述符返回给应用程序,检测就绪事件的算法的时间复杂度为o(n),描述符越长,耗时越长
  4. Poll返回后,需遍历所有描述符,找到就绪的fd

selec poll都只能在相对低效的LT模式,而epoll可以工作在ET高校模式

select和poll都没有从本质上解决,当描述符数量过多时,效率越低的情况

epoll:

     创建一个内核事件表, 把用户关心的文件描述符上的事件都放在内核里的事件表中,从而无须像select,poll那样每次调用都要重复传入文件描述或事件集,但epoll需要使用一个额外的文件描述符,来唯一标识内核中创建的这个内核事件表。

select、poll、epoll区别:

猜你喜欢

转载自blog.csdn.net/YMY_mine/article/details/81383976
今日推荐