epoll和select的区别

来源:互联网 发布:天猫魔盒怎么装软件 编辑:程序博客网 时间:2024/05/16 19:29

要了解epoll和select的区别,首先来理解一下epoll和select各自的功能和属性。poll和epoll和select都是多路复用下的一种机制,多路复用I/O就是通过一种机制,可以监视多个文件描述符,一旦某个文件描述符就绪,就通知程序该文件描述符可以进行读写操作。

select():用于确定一个或多个套接口的状态。
select的几大缺点(不可忽视):
1、每次调用select()的时候,都必须要将fd从用户态转换成内核态,这个开销在fd很多的时候非常大。
2、调用select()的时候,在操作系统内核API都会遍历整个fd集,这会大大影响系统效率。
3、select()可打开的文件描述符的上限太少了,默认是1024个。

epoll ():是Linux下为处理大批量文件描述符而作了改进的poll,是Linux下多路复用I/O接口poll/select的增强版本,能够显著的提高在大量并发连接中只有少数连接活跃的系统CPU利用率。它在获取事件的时候,不会将整个文件描述符集全部遍历,只需要遍历那些被系统API异步唤醒后放入Ready队列的文件描述符。有两种触发的方式,分别是边沿触发和水平触发方式。
因为epoll是poll和select的改进版,所以对于select的缺点也作了相应的处理。epoll里面有三个函数,分别是:epoll_create(用于创建一个epoll句柄), epoll_wait(用于等待一个事件), epoll_ctl(用于注册要监听的事件类型).
1、对于第一个缺点,epoll的解决方案在epoll_ctl函数中。每次注册新的事件到epoll句柄中时(在epoll_ctl中指定EPOLL_CTL_ADD)重点内容,会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。
2、对于第二个缺点,epoll的解决方案不像select或poll一样每次都把current轮流加入fd对应的设备等待队列中,而只在epoll_ctl时把current挂一遍(这一遍必不可少)并为每个fd指定一个回调函数,当设备就绪,唤醒等待队列上的等待者时,就会调用这个回调函数,而这个回调函数会把就绪的fd加入一个就绪链表)。epoll_wait的工作实际上就是在这个就绪链表中查看有没有就绪的fd(利用schedule_timeout()实现睡一会,判断一会的效果,和select实现中的第7步是类似的)。
3、对于第三个缺点,epoll没有这个限制,它所支持的FD上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1GB内存的机器上大约是10万左右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。
区别:1、select在每次被调用的时候,都会讲所有fd从用户态转换成内核态,而epoll只是在事件注册的时候只拷贝一次fd而已。提高了效率。
2、对于select来说,在每次醒着的时候,都需要将整个fd遍历一遍,而对于epoll来说,只需要在current的时候挂一遍fd,然后设置一个回调函数,当设备准备完成时,就调用一个回调函数将对应的文件描述符返还给进程,所以在时间上要大大的提高于select。
3、select的文件描述符的上限默认是1024,但是epoll没有这个限制,可以远大于1024,因为它只和系统的内存大小有关,而不受限于一个定值。

0 0