Linus中epoll特点和使用,以及select、poll、epoll的相互的优缺点 后附代码

i/o复用:select、poll、epoll

其中,epoll是Linus特有的i/o复用函数,在实现与使用上与select、poll有很大的差异。

epoll:

每轮循环:都要从用户空间往内核空间拷数据

内核轮询:检测每个描述符有没有就绪     O(n)

io函数返回后,遍历每个描述符,找到有事件就绪的描述符     O(n)

epoll_create() :创建内核事件表      红黑树

epoll_ctl(): 向内核事件表   添加、删除、修改

epoll_weit(): 只返回有就绪事件的描述符

LT模式:描述符事件就绪后,如果用户没有处理完数据,epoll会继续提醒,直到处理完

ET模式(高效模式):描述符上事件就绪后,无论用户有没有处理完数据,epoll只会处理一次  EPOLL|N|

添加头文件#include<fcntl.h>

fcntl(fd,F_GETFL);

oldflg|O_NONBLOCK

(ET模式必须使用描述符非堵塞模式)

poll:循环遍历得到就绪描述符 O(n)

epoll:有内核事件表,描述符直接+1 O(1)

           适用于  描述符多,就绪事件少

select:适用于 描述符少,就绪事件多的情况 O(n)

epoll与select和poll相比的优缺点:

1、select、poll

     每次循环都需要从用户空间向内核空间传递数据

     epoll

     直接在内核空间创建事件表,每个描述符只需要传递一次

2、select、poll

     在内核中以轮询的方式检测有就绪事件的描述符  O(n)

      epoll

      在每个描述符上注册回调函数,事件就绪后,执行回调函数,描述符添加到就绪队 O(n)

3、select、poll

      返回后,需要遍历所有文件描述符,才能找到就绪的 O(n)

      epoll

      直接找到就绪描述符,不需要遍历所有描述符 O(1)

代码如下

猜你喜欢

转载自blog.csdn.net/obitosbb/article/details/89600398