如果您无法下载资料,请参考说明:
1、部分资料下载需要金币,请确保您的账户上有足够的金币
2、已购买过的文档,再次下载不重复扣费
3、资料包下载后请先用软件解压,在使用对应软件打开
作者:董昊(要转载的同学帮忙把名字和博客链接http://donghao.org/uii/带上,多谢了!)poll和epoll的使用应该不用再多说了。当fd很多时,使用epoll比poll效率更高。我们通过内核源码分析来看看到底是为什么。poll剖析poll系统调用:intpoll(structpollfd*fds,nfds_tnfds,inttimeout);内核2.6.9对应的实现代码为:[fs/select.c-->sys_poll]456asmlinkagelongsys_poll(structpollfd__user*ufds,unsignedintnfds,longtimeout)457{458structpoll_wqueuestable;459intfdcount,err;460unsignedinti;461structpoll_list*head;462structpoll_list*walk;463464/*Doasanitycheckonnfds...*//*用户给的nfds数不可以超过一个structfile结构支持的最大fd数(默认是256)*/465if(nfds>current->files->max_fdset&&nfds>OPEN_MAX)466return-EINVAL;467468if(timeout){469/*Carefulaboutoverflowintheintermediatevalues*/470if((unsignedlong)timeout<MAX_SCHEDULE_TIMEOUT/HZ)471timeout=(unsignedlong)(timeout*HZ+999)/1000+1;472else/*Negativeoroverflow*/473timeout=MAX_SCHEDULE_TIMEOUT;474}475476poll_initwait(&table);其中poll_initwait较为关键,从字面上看,应该是初始化变量table,注意此处table在整个执行poll的过程中是很关键的变量。而structpoll_table其实就只包含了一个函数指针:[fs/poll.h]16/*17*structuresandhelpersforf_op->pollimplementations18*/19typedefvoid(*poll_queue_proc)(structfile*,wait_queue_head_t*,structpoll_table_struct*);2021typedefstructpoll_table_struct{22poll_queue_procqproc;23}poll_table;现在我们来看看poll_initwait到底在做些什么[fs/select.c]57void__pollwait(structfile*filp,wait_queue_head_t*wait_address,poll_table*p);5859voidpoll_initwait(structpoll_wqueues*pwq)60{61&(pwq->pt)->qproc=__pollwait;/*此行已经被我“翻译”了,方便观看*/62pwq->error=0;63pwq->table=NULL;64}很明显,poll_initwait的主要动作就是把table变量的成员poll_table对应的回调函数置为__pollwait。这个__pollwait不仅是poll系统调用需要,select系统调用也一样是用这个__pollwait,说白了,这是个操作系统的异步操作的“御用”回调函数。当然了,epoll没有用这个,它另外新增了一个回调函数,以达到其高效运转的目的,这是后话,暂且不表。我们先不讨论__pollwait的具体实现,还是继续看sys_poll:[fs/select.c-->sys_poll]478head=NULL;479walk=NULL;480i=nfds;481err=-ENOMEM;482while(i!=0){483structpoll_list*pp;484pp=kmalloc(sizeof(structpoll_list)+485sizeof(structpollfd)*486(i>POLLFD_PER_PAGE?POLLFD_PER_PAGE:i),487GFP_KERNEL);488if(pp==NULL)489gotoout_fds;490pp->next=NULL;49