select、poll、epoll的比较

select

优点:
能同时监听多个描述符,一旦每个描述符就绪,就能够通知应用程序进行响应的读写操作。

缺点:

  1. 每次调用都需要将fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大;
  2. 每次调用select都需要遍历所有fd,当fd集合很大时开销很大;
  3. select支持的文件描述符数量太小,默认是1024(或2048),可通过修改FD_SETSIZE值来更改.

poll

poll和select实现上差不多,只是描述fd集合的方式不同。poll使用pollfd结构而不是select的fd_set结构。

epoll

epoll就是对select和poll的改进。

  1. 针对select的第一个缺点,epoll是在epoll_ctl函数中,每次注册新的事件到epoll句柄(指定EPOLL_CTL_ADD)时,会把所有的fd拷贝进内核,而不是在epoll_wait时重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。
  2. 针对select的第二个缺点,epoll是在epoll_ctl时为每个fd指定一个回调函数,当设备就绪、唤醒等待队列上的等待者时,就会回调这个回调函数,而这个回调函数就会把就绪的fd加入到一个就绪的链表中。epoll_wait的工作实际上就是在这个链表中查看有没有就绪的fd。
  3. 针对select的第三个缺点,epoll所支持的fd上限是最大解打开文件的数目,这个数字一般远远大于2048,。具体数目可以查看/proc/sys/fs/file-max查看,一般来说这个数目和系统内存关系很大。

水平触发(LT)和边缘触发(ET)

水平触发:文件描述符关联的读内核缓冲区非空,有数据可以读取,或者与该文件描述符关联的写缓冲区不满,用空间可以写入时,就一直发出可读/可写信号。

边缘触发:当文件描述符关联的内核读缓冲区右空转换为非空时,则发出可读信号进行通知;当文件描述符所关联的内核写缓冲区由满转换为不满时,则发出可写信号进行通知。

两者的区别在于,水平触发只要读缓冲区有数据,或写缓冲区非满状态下,就会一直触发可读/可写信号,而边缘触发则只仅仅只在状态发生改变时通知一次。

posted @ 2019-07-22 15:35  星星,风,阳光  阅读(195)  评论(0编辑  收藏  举报