epoll与select\poll区别

//转载别人的转载, 所以也不知道原处是哪里了, 请原谅.


文章一:

         最近有朋友在面试的时候被问了select 和epoll效率差的原因,和一般人一样,大部分都会回答select是轮询、epoll是触发式的,所以效率高。 
        

         最近有朋友在面试的时候被问了select 和epoll效率差的原因,和一般人一样,大部分都会回答select是轮询、epoll是触发式的,所以效率高。 



 


         select 模式低效是由select的定义所决定的,与操作系统实现无关,任何内核在实现select时必须做轮循,才能知道这些socket的情况,这是会消耗 cpu的。此外,当你拥有一个很大socket集的时候,尽管任一时间只有小部分的socket是"活跃"的,但每次你都不得不将所有的socket填入到一个FD_SET中,这也会消耗一些cpu,并且当select返回后,处理业务时你可能还需要做“上下文映射”,同样也会有一些性能影响,因此 select比epoll相对低效。 

文章2:

linux提供了selectpollepoll接口来实现IO复用,三者的原型如下所示,本文从参数、实现、性能等方面对三者进行对比。

 

int select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout);

int poll(struct pollfd *fds, nfds_t nfds, int timeout);

int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout);

 

selectpollepoll_wait参数及实现对比

1.  select的第一个参数nfdsfdset集合中最大描述符值加1fdset是一个位数组,其大小限制为__FD_SETSIZE1024),位数组的每一位代表其对应的描述符是否需要被检查。

 

select的第二三四个参数表示需要关注读、写、错误事件的文件描述符位数组,这些参数既是输入参数也是输出参数,可能会被内核修改用于标示哪些描述符上发生了关注的事件。所以每次调用select前都需要重新初始化fdset

 

timeout参数为超时时间,该结构会被内核修改,其值为超时剩余的时间。

 

select对应于内核中的sys_select调用,sys_select首先将第二三四个参数指向的fd_set拷贝到内核,然后对每个被SET的描述符调用进行poll,并记录在临时结果中(fdset),如果有事件发生,select会将临时结果写到用户空间并返回;当轮询一遍后没有任何事件发生时,如果指定了超时时间,则select会睡眠到超时,睡眠结束后再进行一次轮询,并将临时结果写到用户空间,然后返回。

 

select返回后,需要逐一检查关注的描述符是否被SET(事件是否发生)。

 

2.  pollselect不同,通过一个pollfd数组向内核传递需要关注的事件,故没有描述符个数的限制,pollfd中的events字段和revents分别用于标示关注的事件和发生的事件,故pollfd数组只需要被初始化一次。

 

poll的实现机制与select类似,其对应内核中的sys_poll,只不过poll向内核传递pollfd数组,然后对pollfd中的每个描述符进行poll,相比处理fdset来说,poll效率更高。

 

poll返回后,需要对pollfd中的每个元素检查其revents值,来得指事件是否发生。

 

3.  epoll通过epoll_create创建一个用于epoll轮询的描述符,通过epoll_ctl添加/修改/删除事件,通过epoll_wait检查事件,epoll_wait的第二个参数用于存放结果。

 

epollselectpoll不同,首先,其不用每次调用都向内核拷贝事件描述信息,在第一次调用后,事件信息就会与对应的epoll描述符关联起来。另外epoll不是通过轮询,而是通过在等待的描述符上注册回调函数,当事件发生时,回调函数负责把发生的事件存储在就绪事件链表中,最后写到用户空间。

 

epoll返回后,该参数指向的缓冲区中即为发生的事件,对缓冲区中每个元素进行处理即可,而不需要像pollselect那样进行轮询检查。

 

selectpollepoll_wait性能对比

selectpoll的内部实现机制相似,性能差别主要在于向内核传递参数以及对fdset的位操作上,另外,select存在描述符数的硬限制,不能处理很大的描述符集合。这里主要考察pollepoll在不同大小描述符集合的情况下性能的差异。

 

 

测试程序会统计在不同的文件描述符集合的情况下,1spollepoll调用的次数。统计结果如下,从结果可以看出,对poll而言,每秒钟内的系统调用数目虽集合增大而很快降低,而epoll基本保持不变,具有很好的扩展性。

 

描述符集合大小

poll

epoll

1

331598

258604

10

330648

297033

100

91199

288784

1000

27411

296357

5000

5943

288671

10000

2893

292397

25000

1041

285905

50000

536

293033

100000

224

285825

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值