linux内核epoll实现分析

为了更好的分享体验,博客搬迁至极客驿站 ,欢迎查阅

epoll与select/poll的区别

     select,poll,epoll都是IO多路复用的机制。I/O多路复用就通过一种机制,可以监视多个描述符,一旦某个描述符就绪,能够通知程序进行相应的操作。

     select的本质是采用32个整数的32位,即32*32= 1024来标识,fd值为1-1024。当fd的值超过1024限制时,就必须修改FD_SETSIZE的大小。这个时候就可以标识32*max值范围的fd。
     poll与select不同,通过一个pollfd数组向内核传递需要关注的事件,故没有描述符个数的限制,pollfd中的events字段和revents分别用于标示关注的事件和发生的事件,故pollfd数组只需要被初始化一次。
     epoll还是poll的一种优化,返回后不需要对所有的fd进行遍历,在内核中维持了fd的列表。select和poll是将这个内核列表维持在用户态,然后传递到内核中。与poll/select不同,epoll不再是一个单独的系统调用,而是由epoll_create/epoll_ctl/epoll_wait三个系统调用组成,后面将会看到这样做的好处。epoll在2.6以后的内核才支持。

select/poll的几大缺点:
1、每次调用select/poll,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
2、同时每次调用select/poll都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
3、针对select支持的文件描述符数量太小了,默认是1024

为什么epoll相比select/poll更高效

     传统的poll函数相当于每次调用都重起炉灶,从用户空间完整读入ufds,完成后再次完全拷贝到用户空间,另外每次poll都需要对所有设备做至少做一次加入和删除等待队列操作,这些都是低效的原因。

     epoll的解决方案中。每次注册新的事件到epoll句柄中时(在epoll_ctl中指定EPOLL_CTL_ADD),会把所有的fd拷贝进内核,而不是在epoll_wait的时候重复拷贝。epoll保证了每个fd在整个过程中只会拷贝一次。select, poll和epoll都是使用waitqueue调用callback函数去wakeup你的异步等待线程的,如果设置了timeout的话就起一个hrtimer,select和poll的callback函数并没有做什么事情,但epoll的waitqueue callback函数把当前的有效fd加到ready list,然后唤醒异步等待进程,所以epoll函数返回的就是这个ready list, ready list中包含所有有效的fd,这样一来kernel不用去遍历所有的fd,用户空间程序也不用遍历所有的fd,而只是遍历返回有效fd链表。

为什么要实现eventpollfs

1、可以在内核里维护一些信息,这些信息在多次epoll_wait间是保持的,比如所有受监控的文件描述符
2、epoll本身也可以被poll/epoll

加入的epoll的FD需要满足什么条件

理论上只要是一个文件就可以加入epoll,Linux本身的一个设计思想也是一切皆文件。file结构也体现了对epoll的支持。

struct file {
	/*
	 * fu_list
  • 1
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值