- 浏览: 600296 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
oldrat:
还给出了 给出“对于多条A记录是采用什么策略返回IP”的结论, ...
【转载】关于java dns cache (域名缓存时间) -
snowing0427:
特地登录来感谢一下楼主~!!!
nginx里的break和last -
夏日小草:
403禁止了。
User Agent信息大全 -
uag:
比如从请求头里的$HOST变量里获取。(针对nginx,需要加 ...
nginx替换apache中的一个跳转问题 -
thinktothings:
修改Makefile文件 在哪,怎么修改?
使用sz,rz命令来上传和下载文件
epoll是多路复用IO(I/O Multiplexing)中的一种方式,但是仅用于linux2.6以上内核,在开始讨论这个问题之前,先来解释一下为什么需要多路复用IO.
以一个生活中的例子来解释.
假设你在大学中读书,要等待一个朋友来访,而这个朋友只知道你在A号楼,但是不知道你具体住在哪里,于是你们约好了在A号楼门口见面.
如果你使用的阻塞IO模型来处理这个问题,那么你就只能一直守候在A号楼门口等待朋友的到来,在这段时间里你不能做别的事情,不难知道,这种方式的效率是低下的.
现在时代变化了,开始使用多路复用IO模型来处理这个问题.你告诉你的朋友来了A号楼找楼管大妈,让她告诉你该怎么走.这里的楼管大妈扮演的就是多路复用IO的角色.
进一步解释select和epoll模型的差异.
select版大妈做的是如下的事情:比如同学甲的朋友来了,select版大妈比较笨,她带着朋友挨个房间进行查询谁是同学甲,你等的朋友来了,于是在实际的代码中,select版大妈做的是以下的事情:
int n = select(&readset,NULL,NULL,100); for (int i = 0; n > 0; ++i) { if (FD_ISSET(fdarray[i], &readset)) { do_something(fdarray[i]); --n; } }
epoll版大妈就比较先进了,她记下了同学甲的信息,比如说他的房间号,那么等同学甲的朋友到来时,只需要告诉该朋友同学甲在哪个房间即可,不用自己亲自带着人满大楼的找人了.于是epoll版大妈做的事情可以用如下的代码表示:
在epoll中,关键的数据结构epoll_event定义如下:
typedef union epoll_data { void *ptr; int fd; __uint32_t u32; __uint64_t u64; } epoll_data_t; struct epoll_event { __uint32_t events; /* Epoll events */ epoll_data_t data; /* User data variable */ };
可以看到,epoll_data是一个union结构体,它就是epoll版大妈用于保存同学信息的结构体,它可以保存很多类型的信息:fd,指针,等等.有了这个结构体,epoll大妈可以不用吹灰之力就可以定位到同学甲.
别小看了这些效率的提高,在一个大规模并发的服务器中,轮询IO是最耗时间的操作之一.再回到那个例子中,如果每到来一个朋友楼管大妈都要全楼的查询同学,那么处理的效率必然就低下了,过不久楼底就有不少的人了.
对比最早给出的阻塞IO的处理模型, 可以看到采用了多路复用IO之后, 程序可以自由的进行自己除了IO操作之外的工作, 只有到IO状态发生变化的时候由多路复用IO进行通知, 然后再采取相应的操作, 而不用一直阻塞等待IO状态发生变化了.
从上面的分析也可以看出,epoll比select的提高实际上是一个用空间换时间思想的具体应用.
我们目前的网络模型大都是epoll的,因为epoll模型会比select模型性能高很多, 尤其在大连接数的情况下,作为后台开发人员需要理解其中的原因。
select/epoll的特点
select的特点:select 选择句柄的时候,是遍历所有句柄,也就是说句柄有事件响应时,select需要遍历所有句柄才能获取到哪些句柄有事件通知,因此效率是非常低。但是如果连接很少的情况下, select和epoll的LT触发模式相比, 性能上差别不大。
这里要多说一句,select支持的句柄数是有限制的, 同时只支持1024个,这个是句柄集合限制的,如果超过这个限制,很可能导致溢出,而且非常不容易发现问题, TAF就出现过这个问题, 调试了n天,才发现:)当然可以通过修改linux的socket内核调整这个参数。
epoll的特点:epoll对于句柄事件的选择不是遍历的,是事件响应的,就是句柄上事件来就马上选择出来,不需要遍历整个句柄链表,因此效率非常高,内核将句柄用红黑树保存的。
对于epoll而言还有ET和LT的区别,LT表示水平触发,ET表示边缘触发,两者在性能以及代码实现上差别也是非常大的。
epoll的LT和ET的区别
LT:水平触发,效率会低于ET触发,尤其在大并发,大流量的情况下。但是LT对代码编写要求比较低,不容易出现问题。LT模式服务编写上的表现是:只要有数据没有被获取,内核就不断通知你,因此不用担心事件丢失的情况。
ET:边缘触发,效率非常高,在并发,大流量的情况下,会比LT少很多epoll的系统调用,因此效率高。但是对编程要求高,需要细致的处理每个请求,否则容易发生丢失事件的情况。
下面举一个列子来说明LT和ET的区别(都是非阻塞模式,阻塞就不说了,效率太低):
采用LT模式下, 如果accept调用有返回就可以马上建立当前这个连接了,再epoll_wait等待下次通知,和select一样。
但是对于ET而言,如果accpet调用有返回,除了建立当前这个连接外,不能马上就epoll_wait还需要继续循环accpet,直到返回-1,且errno==EAGAIN,TAF里面的示例代码:
if(ev.events & EPOLLIN) { do { struct sockaddr_in stSockAddr; socklen_t iSockAddrSize = sizeof(sockaddr_in); TC_Socket cs; cs.setOwner(false); //接收连接 TC_Socket s; s.init(fd, false, AF_INET); int iRetCode = s.accept(cs, (struct sockaddr *) &stSockAddr, iSockAddrSize); if (iRetCode > 0) { ...建立连接 } else { //直到发生EAGAIN才不继续accept if(errno == EAGAIN) { break; } } }while(true); }
同样,recv/send等函数, 都需要到errno==EAGAIN
从本质上讲:与LT相比,ET模型是通过减少系统调用来达到提高并行效率的。
epoll ET详解
ET模型的逻辑:内核的读buffer有内核态主动变化时,内核会通知你, 无需再去mod。写事件是给用户使用的,最开始add之后,内核都不会通知你了,你可以强制写数据(直到EAGAIN或者实际字节数小于 需要写的字节数),当然你可以主动mod OUT,此时如果句柄可以写了(send buffer有空间),内核就通知你。
这里内核态主动的意思是:内核从网络接收了数据放入了读buffer(会通知用户IN事件,即用户可以recv数据)
并且这种通知只会通知一次,如果这次处理(recv)没有到刚才说的两种情况(EAGIN或者实际字节数小于 需要读写的字节数),则该事件会被丢弃,直到下次buffer发生变化。
与LT的差别就在这里体现,LT在这种情况下,事件不会丢弃,而是只要读buffer里面有数据可以让用户读,则不断的通知你。
另外对于ET而言,当然也不一定非send/recv到前面所述的结束条件才结束,用户可以自己随时控制,即用户可以在自己认为合适的时候去设置IN和OUT事件:
1 如果用户主动epoll_mod OUT事件,此时只要该句柄可以发送数据(发送buffer不满),则epoll
_wait就会响应(有时候采用该机制通知epoll_wai醒过来)。
2 如果用户主动epoll_mod IN事件,只要该句柄还有数据可以读,则epoll_wait会响应。
这种逻辑在普通的服务里面都不需要,可能在某些特殊的情况需要。 但是请注意,如果每次调用的时候都去epoll mod将显著降低效率,已经吃过几次亏了!
因此采用et写服务框架的时候,最简单的处理就是:
建立连接的时候epoll_add IN和OUT事件, 后面就不需要管了
每次read/write的时候,到两种情况下结束:
1 发生EAGAIN
2 read/write的实际字节数小于 需要读写的字节数
对于第二点需要注意两点:
A:如果是UDP服务,处理就不完全是这样,必须要recv到发生EAGAIN为止,否则就丢失事件了
因为UDP和TCP不同,是有边界的,每次接收一定是一个完整的UDP包,当然recv的buffer需要至少大于一个UDP包的大小
随便再说一下,一个UDP包到底应该多大?
对于internet,由于MTU的限制,UDP包的大小不要超过576个字节,否则容易被分包,对于公司的IDC环境,建议不要超过1472,否则也比较容易分包。
B 如果发送方发送完数据以后,就close连接,这个时候如果recv到数据是实际字节数小于读写字节数,根据开始所述就认为到EAGIN了从而直接返回,等待下一次事件,这样是有问题的,close事件丢失了!
因此如果依赖这种关闭逻辑的服务,必须接收数据到EAGIN为止,例如lb。
本文收集自:
Vimer的程序世界
发表评论
-
ntp的客户端配置
2013-02-25 19:42 0——背景简介: ... -
installing goagent on ubuntu(12.04 LTS)
2012-12-14 23:39 4409If you want to access some bloc ... -
Fedora17-command not found-命令延时
2012-11-13 14:35 1340Fedora 17下不小心输入错误一条命令,提示command ... -
can't identify protocol问题的定位和解决
2012-10-08 19:08 13452在观摩了一个关于性能问题排查的PPT之后试着用lsof命令来列 ... -
【转载】Linux日志管理:实例详解syslog
2012-09-29 16:40 2951=============================== ... -
使用nfs挂载远端主机目录到本地
2012-09-06 00:18 3192由于一个应用的需要,要使用这方面的知识。 就是两台机器,1 ... -
fedora 17继续折腾
2012-08-22 13:37 1613今天来折腾fedora17了…… 安装的64位: ... -
再谈yum配置
2012-08-18 15:13 1079配置环境永远是最重要的第一步。 在我又开始折腾虚拟机的 ... -
一个简单的监控后台需要什么?
2012-08-07 23:55 1824今晚突然想到要给之前学校的一个网站做一个监控的后台, 一些常 ... -
yum源的配置以及一个错误解决
2012-07-30 15:16 2337今天刚拿到一台新机器,系统为Red Hat Enterpris ... -
SSH建立信任关系实现免输密码登陆
2012-07-18 19:09 3826为了方便管理,在需要频繁登陆机器,特别是在机器众多的时候,免密 ... -
关于代理和反向代理
2012-07-12 16:10 1150其实简单来讲,代理和反向代理可以这么来理解: 代理: ... -
RHEL-AS4安装yum
2012-05-11 02:15 3656我的系统版本: Red Hat Enterprise Lin ... -
Ubuntu8.04安装CP-168U的串口连接问题
2012-05-05 18:26 2280毕业设计需要用到1托8的MOXA CP-168U卡做一个交换机 ... -
制作用U盘引导安装Ubuntu12.04
2012-05-02 14:04 38704由于之前刻了两次碟,均在安装完一次系统之后就损坏了。。。 所 ... -
【转载】su和sudo命令的区别与使用技巧
2012-04-12 23:21 1528一. 使用 su 命令临时切换用户身份 1、su ... -
Linux内核学习步骤
2011-11-25 10:33 2595今日在论坛中看到大牛谈如何学习Linux内核,于是摘录的 ... -
【转】什么是Linux的僵尸(zombie)进程
2011-10-08 15:55 2071可能很少 ... -
Linux中的颜色方案
2011-09-28 17:18 2932在linux下可以自定义自己的颜色方案,不管是linux命令提 ... -
取得jboss的版本信息
2011-09-26 20:44 14256由于写脚本的需要, 要获取jboss的版本信息。 大 ...
相关推荐
17socket编程(十二) select限制 poll 18socket编程(十三) epoll使用 epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程...
自学Linux网络编程关于socket...重点介绍多路I/O转接服务器的实现,包括select函数poll函数epoll函数;最后介绍了UDP协议的服务器编写和本地套接字的程序实现。资源里面有笔记,C语言代码,参考书及参考书包含的程序。
epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 ...
epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 UNIX域地址...
epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 ...
epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 ...
epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 ...
epoll与select、poll区别 epoll LT/ET模式 19socket编程(十四) UDP特点 UDP客户/服务基本模型 UDP回射客户/服务器 UDP注意点 20socket编程(十五) udp聊天室实现 21socket编程(十六) UNIX域协议特点 ...
抽象了Win32 Select、Linux epoll和FreeBSD kqueue的多路复用API。统一了三者水平模式(Level Triggered)的语义(一套代码在Win32/Linux/FreeBSD运行结果是一样的),Linux上也支持了边缘模式(Edge Triggered)。 ...
09 select与epoll的实现区别 第36章 01 异步IO 02 selectors模块介绍 03 selectors模块应用 04 作业介绍 第37章 01 selctors实现文件上传与下载 02 html的介绍 03 html文档树的概念 04 meta标签以及一些基本标签...
介绍 您的软件可能想从多个来源获取事件。 这包括计时器,网络套接字,文件系统更改,输入事件,操作系统信号,窗口事件等。 基本上,您可以从单一的wait()或poll()调用中统一访问所有这些事件,并使用单个接口处理...
本人转量化投资,不再写其他代码。 介绍 5G、大数据浪潮来袭。对设备与设备的通信提出了更高要求。为此开发了这个高性能高并发的网络框架。 mushroom是一个高性能的跨全平台的socket网络框架。 mushroom支持TCP、UDP...
封装epoll多路I/O系统调用,提供增加、删除和等待操作接口。 2.1.5. 插件管理器(PluginMngr) 加载插件并接受其注册,维护插件对象容器并提供调用其处理函数的外部接 口。 2.2. 网络通信 2.2.1. 哈希器(Hash) 封装...