版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、select,poll,epoll三种通信模式的比较,主要介绍三种模式的基本内容,以及三种模式对比的优缺点,select为什么会出现,先看一下下面的这句代码: int iresult = recv(s, buffer,1024); 这是用来接收数据的,在默认的阻塞模式下的套接字里,recv会阻塞在那里,直到套接字连接上有数据可读,把数据读到buffer里后recv函数才会返 回,不然就会一直阻塞在那里。在单线程的程序里出现这种情况会导致主线程(单线程程序里只有一个默认的主线程)被阻塞,这样整个程序被锁死在这里,如果永远没数据发送过来,那么程序就会被永远锁死。这个问题可以用多线程解决,但是在有多
2、个套接字连接的情况下,这不是一个好的选择,扩展性很差。 再看代码:,int iresult = ioctlsocket(s, fiobio, (unsigned long *) 这一次recv的调用不管套接字连接上有没有数据可以接收都会马上返回。原因就在于我们用ioctlsocket把套接字设置为非阻塞模式了。不过 你跟踪 一下就会发现,在没有数据的情况下,recv确实是马上返回了,但是也返回了一个错误:wsaewouldblock,意思就是请求的操作没有成功完成。 看到这里很多人可能会说,那么就重复调用recv并检查返回值,直到成功为止,但是这样做效率很成问题,开销太大。 select模型的
3、出现就是为了解决上述问题。 select模型的关键是使用一种有序的方式,对多个套接字进行统一管理与调度 。,函数原型: int select (int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); nfds: 整型变量,他比所有的文件描述符集合中的最大值大1(为什么大1,因为文件描述符从0开始计数,这里代表数量吧) readfds:文件描述符监视文件集合中的任何文件是否有数据可读,可以被recv()、read()等进行读数据操作 writefds:文件描述符监视文件集合
4、中的任何文件是否有数据可写,可以被send()、write()等进行写数据操作 exceptfds:监视文件集中是否发生错误 timeout: 设置所监视的文件集合中的事件没有发生时,最长的等待时间,关于fd_set的一些说明 1. fd_set 结构体 fd_set是文件句柄的集合。 fd_zero 清空这个集合; fd_set往这个集合里面加入一个文件句柄; fd_isset 查看某一个文件句柄是否被设置了; fd_set 是一组文件描述符(fd)的集合。由于fd_set类型的长度在不同平台上不同,因此应该用一组标准的宏定义来处理此类变量: fd_set set; fd_zero( /*
5、判断fd是否处于可用状态 是为true*/ 关于select函数的具体用法,这里就不再阐述,select函数的优缺点,优点:select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,事实上从现在看来,这也是它所剩不多的优点之一。,缺点:有两个很致命的缺点,select的一个缺点在于单个进程能够监视的文件描述符的数量存在最大限制,在linux上一般为1024,不过可以通过修改宏定义甚至重新编译内核的方式提升这一限制。 另外,select()所维护的存储大量文件描述符的数据结构,随着文件描述符数量的增大,其复制的开销也线性增长。同时,由于网络响应时间的延迟使得大量tcp连接处于非活
6、跃状态,但调用select()会对所有socket进行一次线性扫描,所以这也浪费了一定的开销。,poll()函数,int poll(struct pollfd*fds,nfds_t nfds,int timeout); struct pollfd int fd;/*文件描述符*/ short events;/*请求的事件*/ short revents;/*返回的事件*/ events的值及含义 pollin有数据到来,文件描述符可读 pollpri有紧急数据到来 pollout文件可写 pollrdhup流式套接字半关闭 pollerr错误发生 pollhup关闭 pollnval非法请求
7、pollrdnorm与pollin相同(那还写出来) pollrdband优先数据可读 pollwrnorm有pollout相同(汗!) pollwrband优先数据可写,poll函数优缺点:,优点(改进): poll相对于select改进了fdset size的限制,poll没有再使用fdset数组结构,反而使用了pollfd,这样用户可以自定义非常大的pollfd数组,这个pollfd数组在kernel中的表现形式是poll_list链表,这样就不存在了1024的限制了 缺点: 除此之外poll相比select无太大区别,最主要是因为pool与select一样,他们对应的内核函数都是sys
8、_poll,所以随着文件描述符数量的增大,其复制的开销也线性增长。同时,由于网络响应时间的延迟使得大量tcp连接处于非活跃状态 也就是说,当文件描述符很大的情况下,poll的效率也是相当的慢,虽然它能增加描述符的数量,但是效率问题反而更严重了,对比select和poll,epoll具有以下这些优点: 1.支持一个进程打开大数目的socket描述符(fd) select 最不能忍受的是一个进程所打开的fd是有一定限制的,由fd_setsize设置,默认值是2048。对于那些需要支持的上万连接数目的im服务器来说显 然太少了。这时候你一是可以选择修改这个宏然后重新编译内核,不过资料也同时指出这样会
9、带来网络效率的下降,二是可以选择多进程的解决方案(传统的 apache方案),不过虽然linux上面创建进程的代价比较小,但仍旧是不可忽视的,加上进程间数据同步远比不上线程间同步的高效,所以也不是一种完 美的方案。不过 epoll则没有这个限制,它所支持的fd上限是最大可以打开文件的数目,这个数字一般远大于2048,举个例子,在1gb内存的机器上大约是10万左 右,具体数目可以cat /proc/sys/fs/file-max察看,一般来说这个数目和系统内存关系很大。 2.io效率不随fd数目增加而线性下降 传统的select/poll另一个致命弱点就是当你拥有一个很大的socket集合,不过
10、由于网络延时,任一时间只有部分的socket是活跃的, 但是select/poll每次调用都会线性扫描全部的集合,导致效率呈现线性下降。但是epoll不存在这个问题,它只会对活跃的socket进行 操作-这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。那么,只有活跃的socket才会主动的去调用 callback函数,其他idle状态socket则不会,在这点上,epoll实现了一个伪aio,因为这时候推动力在os内核。在一些 benchmark中,如果所有的socket基本上都是活跃的-比如一个高速lan环境,epoll并不比select/poll有什么效率,相
11、 反,如果过多使用epoll_ctl,效率相比还有稍微的下降。但是一旦使用idle connections模拟wan环境,epoll的效率就远在select/poll之上了。,总的来说,select/poll的缺点: 1.每次调用时要重复地从用户态读入参数。 2.每次调用时要重复地扫描文件描述符。 3.每次在调用开始时,要把当前进程放入各个文件描述符的等待队列。在调用结束后, 又把进程从各个等待队列中删除。 epoll的改进: 在执行epoll_create和epoll_ctrl时,已经把用户态的信息保存到内核态了, 所以之后即使反复地调用epoll_wait,也不会重复地拷贝参数,扫描文件描
12、述符,反复地把当前进程放入/放出等待队列。这样就避免了以上的三个缺点。 当然,支持一个进程打开大数目的socket描述符(fd) 也是一个改进,以上都是网上对三种模式的剖析,我来说下我通过写程序后对于这三种模式的理解:(个人理解,如有错误,还望指正) 无所select还是poll,它们的函数都是在一个while循环中,每次都会调用,通过对do_select 和do_poll函数,可以知道,每次两个函数都会扫描整个文件描述符,所以,在文件描述符原来越多的情况下,效率自然就慢了下来 再看epoll,它在循环外面创建epoll_create,然后添加事件epoll_ctl,完了后在循环体内就只有一个
13、epoll_wait,就是说epoll在等,有文件描述符产生,就是直接连接这个函数,这样的话,就省去了遍历整个文件描述符,这样一来,效率自然就高了,epoll的使用,epoll有两种工作方式,分别问lt和et 水平触发(level-triggered,也被称为条件触发)lt: 只要满足条件,就触发一个事件(只要有数据没有被获取,内核就不断通知你) 边缘触发(edge-triggered)et: 每当状态变化时,触发一个事件,epoll,用到的数据结构: typedef union epoll_data void *ptr; int fd; _uint32_t u32; _uint64_t 64
14、; epoll_data_t; struct epoll_event _uint32t events; epoll_data_t data; ;,结构体epoll_event 被用于注册感兴趣的事件和回传所发生待处理的事件,epoll_data联合体用来保存触发事件的某个文件描述符相关的数据 epoll_event events表示感兴趣的事件和被触发的事件,可能的取值为: epollin:对应的文件描述符可以读 epollout:对应的文件描述符可以写 epollpri:紧急数据 epollerr:文件描述符发生错误 epollhup:文件描述符被挂断 epollet:文件描述符有事件发生,
15、epoll的三个函数,epoll的接口非常简单,一共就三个函数: 1. int epoll_create(int size); 创建一个epoll的句柄,size用来告诉内核这个监听的数目一共有多大。这个参数不同于select()中的第一个参数,给出最大监听的fd+1的值。需要注意的是,当创建好epoll句柄后,它就是会占用一个fd值,在linux下如果查看/proc/进程id/fd/,是能够看到这个fd的,所以在使用完epoll后,必须调用close()关闭,否则可能导致fd被耗尽。,2. int epoll_ctl(int epfd, int op, int fd, struct epol
16、l_event *event); epoll的事件注册函数,它不同与select()是在监听事件时告诉内核要监听什么类型的事件,而是在这里先注册要监听的事件类型。第一个参数是epoll_create()的返回值,第二个参数表示动作,用三个宏来表示: epoll_ctl_add:注册新的fd到epfd中; epoll_ctl_mod:修改已经注册的fd的监听事件; epoll_ctl_del:从epfd中删除一个fd; 第三个参数是需要监听的fd,第四个参数是告诉内核需要监听什么事,struct epoll_event结构如下: struct epoll_event _uint32_t even
17、ts; /* epoll events */ epoll_data_t data; /* user data variable */ ; events可以是以下几个宏的集合: epollin :表示对应的文件描述符可以读(包括对端socket正常关闭); epollout:表示对应的文件描述符可以写; epollpri:表示对应的文件描述符有紧急的数据可读(这里应该表示有带外数据到来); epollerr:表示对应的文件描述符发生错误; epollhup:表示对应的文件描述符被挂断; epollet: 将epoll设为边缘触发(edge triggered)模式,这是相对于水平触发(level triggered)来说的。 epolloneshot:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到epoll队列里,3. int epo
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026本科英语面试题及答案
- 2026北京社工面试题题及答案
- 2025年中国环保型电热气化加压垫市场调查研究报告
- 2025年中国火灾报警区域显示器市场调查研究报告
- 2025年中国浴缸冷热水嘴市场调查研究报告
- 2025年中国汽油电喷车喷油嘴清洗剂市场调查研究报告
- 2025年中国多路电池测量仪馈线屏市场调查研究报告
- 2026北京链家面试题及答案
- 异常分娩的护理效果评价
- 老年人长期照护康复计划制定
- 7.5 歌曲 《红河谷》课件(20张)
- 人工智能导论智慧树知到期末考试答案章节答案2024年哈尔滨工程大学
- 新大象版四年级下册科学全册知识点(精编版)
- 磨床操作培训课件
- GB/T 43189-2023核仪器仪表闪烁体和闪烁探测器的命名(标识)以及闪烁体的标准尺寸
- 预制钢筋混凝土方桩图集
- 汽车电工电子技术PPT(高职)完整全套教学课件
- 民用航空器活动区驾驶员笔试备考题库(含答案)
- 三体系管理手册
- 辣椒初加工项目可研
- GB/T 778.1-2018饮用冷水水表和热水水表第1部分:计量要求和技术要求
评论
0/150
提交评论