9、epoll其他花絮

  1. 云栖社区>
  2. 博客>
  3. 正文

9、epoll其他花絮

hopegrace 2011-09-03 13:23:00 浏览266
展开阅读全文

    epoll是做为一个虚拟文件系统来实现的,这样做至少有以下两个好处:

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

2、epoll本身也可以被poll/epoll

    【1epoll的实现中,所等待的设备就绪后,便调用call_back函数,把该设备加入到就绪队列中,避免了像poll那样设备就绪后再次轮询所有设备找就绪者,由O(n)降到O(1)

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

3、epoll的实现代码在fs/EventPoll.c中。【2】中最后简略介绍了一下实现函数,可以看到,epoll等待队列及调用函数。

    Linux的等待队列,实质上是回调函数队列;【3】的后文,有epollpoll等形象对比。

add_wait_queue(whead, &pwq->wait);

4、epoll保存拷入的fd,通过epoll_ctl把所有fd传入内核再一起"wait",这就省掉了不必要的重复拷贝。其次,在epoll_wait时,也不是把current轮流的加入fd对应的设备等待队列,而是在设备等待队列醒来时调用一个回调函数(当然,这就需要“唤醒回调”机制),把产生事件的fd归入一个链表,然后返回这个链表上的fd

一个新创建的epoll文件带有一个struct eventpoll结构,这个结构上再挂一个红黑树,而这个红黑树就是每次epoll_ctlfd存放的地方!【45

5、创建struct eppoll_entry,设置其唤醒回调函数为ep_poll_callback,然后加入设备等待队列。只有这样,当设备就绪,唤醒等待队列上的等待fd时,ep_poll_callback就会被调用。每次调用poll系统调用,操作系统都要把current(当前进程)挂到fd对应的所有设备的等待队列上,可以想象,fd多到上千的时候,这样“挂”法很费事;而每次调用epoll_wait则没有这么罗嗦,epoll只在epoll_ctl时把current挂一遍(这第一遍是免不了的)并给每个fd一个命令“好了就调回调函数”,如果设备有事件了,通过回调函数,会把fd放入rdllist,而每次调用epoll_wait就只是收集rdllist里的fd就可以了——epoll巧妙的利用回调函数,实现了更高效的事件驱动模型。

ep_poll_callback会干什么了——肯定是把红黑树上的收到eventepitem(代表每个fd)插入ep->rdllist中,这样,当epoll_wait返回时,rdllist里就都是就绪的fd了!

比喻如下【3

就像收本子的班长,以前(poll)得一个个学生地去问有没有本子,如果没有,它还得等待一段时间而后又继续问(轮询),现在好了,只走一次(epoll_ctl),如果没有本子,班长就告诉大家去那里交本子(等待队列,回调函数),当班长想起要取本子,就去那里看看或者等待一定时间后离开(epoll_wait),有本子到了就叫醒他,然后取走。

6、linux系统的优点:everything is a file

参考

1http://hi.baidu.com/zty598416146/blog/item/a8a75da5347266ee9152ee3e.html

2http://www.cnblogs.com/xuxm2007/archive/2011/08/15/2139809.html

3http://blog.csdn.net/hairetz/article/details/6337817

4http://donghao.org/uii/

5http://download.csdn.net/source/3571754

6】 讲的详细

http://observer.blog.hexun.com/31993204_d.html

网友评论

登录后评论
0/500
评论
hopegrace
+ 关注