epolllinux下的epoll有什么作用?

epoll  时间:2021-07-12  阅读:()

epoll et和lt模式的区别

EPOLL事件分发系统可以运转在两种模式下:Edge Triggered (ET)、Level Triggered (LT)。

LT是缺省的工作方式,并且同时支持block和no-blocksocket;在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。

如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错误可能性要小一点。

传统的select/poll都是这种模型的代表。

ET是高速工作方式,只支持no-block socket。

在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。

然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了。

但是请注意,如果一直不对这个fd作IO操作(从而导致它再次变成未就绪),内核不会发送更多的通知。

后面才是我想说的内容,既然ET模式是高速模式,那我们进行服务器开发是一定要使用的了,可是查遍文档,也没有找到ET模式的设置方法,到底如何设置和使 用呢?通过反复测试,终于搞明白“EPOLLET”就是ET模式的设置了,也许是我太笨所以才迷惑这么久了,以下就是将TCP套接字hSocket和 epoll关联起来的代码: struct epoll_event struEvent; struEvent.events = EPOLLIN | EPOLLOUT |EPOLLET; struEvent.data.fd = hSocket; epoll_ctl(m_hEpoll, EPOLL_CTL_ADD, hSocket, &struEvent); 如果将监听套接字m_hListenSocket和epoll关联起来,则代码如下: struct epoll_event struEvent; struEvent.events = EPOLLIN | EPOLLET; struEvent.data.fd = m_hListenSocket; epoll_ctl(m_hEpoll, EPOLL_CTL_ADD, m_hListenSocket, &struEvent); 如果想使用LT模式,直接把事件的赋值修改为以下即可,也许这就是缺省的意义吧。

struEvent.events = EPOLLIN | EPOLLOUT; //用户TCP套接字 struEvent.events = EPOLLIN; //监听TCP套接字 不过,通过我的测试确定,这两种模式的性能差距还是非常大的,最大可以达到10倍。

100个连接的压力测试,其他环境都相同,LT模式CPU消耗99%、ET模式15%。

epoll和select的区别

爱应用为您解答: 先说下本文框架,先是问题引出,然后概括两个机制的区别和联系,最后介绍每个接口的用法 一、问题引出 联系区别 问题的引出,当需要读两个以上的I/O的时候,如果使用阻塞式的I/O,那么可能长时间的阻塞在一个描述符上面,另外的描述符虽然有数据但是不能读出来,这样实时性不能满足要求,大概的解决方案有以下几种: 1.使用多进程或者多线程,但是这种方法会造成程序的复杂,而且对与进程与线程的创建维护也需要很多的开销。

(Apache服务器是用的子进程的方式,优点可以隔离用户) 2.用一个进程,但是使用非阻塞的I/O读取数据,当一个I/O不可读的时候立刻返回,检查下一个是否可读,这种形式的循环为轮询(polling),这种方法比较浪费CPU时间,因为大多数时间是不可读,但是仍花费时间不断反复执行read系统调用。

3.异步I/O(asynchronous I/O),当一个描述符准备好的时候用一个信号告诉进程,但是由于信号个数有限,多个描述符时不适用。

4.一种较好的方式为I/O多路转接(I/O multiplexing)(貌似也翻译多路复用),先构造一张有关描述符的列表(epoll中为队列),然后调用一个函数,直到这些描述符中的一个准备好时才返回,返回时告诉进程哪些I/O就绪。

select和epoll这两个机制都是多路I/O机制的解决方案,select为POSIX标准中的,而epoll为Linux所特有的。

区别(epoll相对select优点)主要有三: 1.select的句柄数目受限,在linux/posix_types.h头文件有这样的声明:#define __FD_SETSIZE 1024 表示select最多同时监听1024个fd。

而epoll没有,它的限制是最大的打开文件句柄数目。

2.epoll的最大好处是不会随着FD的数目增长而降低效率,在selec中采用轮询处理,其中的数据结构类似一个数组的数据结构,而epoll是维护一个队列,直接看队列是不是空就可以了。

epoll只会对"活跃"的socket进行操作---这是因为在内核实现中epoll是根据每个fd上面的callback函数实现的。

那么,只有"活跃"的socket才会主动的去调用 callback函数(把这个句柄加入队列),其他idle状态句柄则不会,在这点上,epoll实现了一个"伪"AIO。

但是如果绝大部分的I/O都是“活跃的”,每个I/O端口使用率很高的话,epoll效率不一定比select高(可能是要维护队列复杂)。

3.使用mmap加速内核与用户空间的消息传递。

无论是select,poll还是epoll都需要内核把FD消息通知给用户空间,如何避免不必要的内存拷贝就很重要,在这点上,epoll是通过内核于用户空间mmap同一块内存实现的。

二、接口 1)select 1. int select(int maxfdp1, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict exceptfds, struct timeval *ptr); struct timeval{ _sec; _usec; } 有三种情况ptr == NULL 永远等待ptr-&_sec == 0 &&ptr-&_usec == 0 完全不等待;不等于0的时候为等待的时间。

select的三个指针都可以为空,这时候select提供了一种比sleep更精确的定时器。

注意select的第一个参数maxfdp1并不是描述符的个数,而是最大的描述符加1,一是起限制作用,防止出错,二来可以给内核轮询的时候提供一个上届,提高效率。

select返回-1表示出错,0表示超时,返回正值是所有的已经准备好的描述符个数(同一个描述符如果读和写都准备好,对结果影响是+2)。

2.int FD_ISSET(int fd, fd_set *fdset); fd在描述符集合中非0,否则返回0 3.int FD_CLR(int fd, fd_set *fd_set); int FD_SET(int fd, fd_set *fdset) ;int FD_ZERO(fd_set *fdset); 用一段linux 中man里的话“FD_ZERO() clears a set.FD_SET() and FD_CLR() respectively add and remove a given file descriptor from a set. FD_ISSET() tests to see if a file descriptor is part of the set; this is useful after select() returns.”这几个函数与描述符的0和1没关系,只是添加删除检测描述符是否在set中。

2)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 epoll_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 events; /* 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队列里 关于epoll工作模式ET,LT LT(level triggered)是缺省的工作方式,并且同时支持block和no-block socket.在这种做法中,内核告诉你一个文件描述符是否就绪了,然后你可以对这个就绪的fd进行IO操作。

如果你不作任何操作,内核还是会继续通知你的,所以,这种模式编程出错误可能性要小一点。

传统的select/poll都是这种模型的代表. ET (edge-triggered)是高速工作方式,只支持no-block socket。

在这种模式下,当描述符从未就绪变为就绪时,内核通过epoll告诉你。

然后它会假设你知道文件描述符已经就绪,并且不会再为那个文件描述符发送更多的就绪通知,直到你做了某些操作导致那个文件描述符不再为就绪状态了,但是请注意,如果一直不对这个fd作IO操作(从而导致它再次变成未就绪),内核不会发送更多的通知(only once) 3. int epoll_wait(int epfd, struct epoll_event * events, int maxevents, int timeout) 等待事件的产生,类似于select()调用。

参数events用来从内核得到事件的集合,maxevents告之内核这个events有多大,这个maxevents的值不能大于创建epoll_create()时的size,参数timeout是超时时间(毫秒,0会立即返回,-1永久阻塞)。

该函数返回需要处理的事件数目,如返回0表示已超时。

epoll并发量最大能达到多少

按照题主的意思 是根据内存去算一个最大并发的连接数. 那么首先要找出来单个连接消耗内存的地方. 第一个首先是socket buffer. read 和write 分别有一个, 默认大小在 复制代码 代码如下: /proc//ipv4/tcp_rmem (for read) /proc//ipv4/tcp_wmem (for write) 默认大小都是87K和16K, 最低是4K和4K, 最高是2M,2M, 实际使用默认值e799bee5baa6e997aee7ad94e4b893e5b19e31333339663939最低也要保留8K,8K. 然后是逻辑IO缓冲区 就是比如你监听了recv事件 事件来了 你要有内存可用(一般都是socket建立起就分配好,断开才会释放的). 这个内存是自己写socket程序时候自己控制的, 最低也要4K,4K, 实际使用8K,8K至少. 现在设定一个优化方案和使用场景, 首先假设4G内存全部为空闲(系统和其他进程也要内存的…. 假如网络包的大小都可以控制在4K以下, 假设所有连接的网络都不会拥堵, 或者拥堵时候的总量在4K以下: 一个连接的内存消耗是4+4+4+4=16K 4G/16K=26.2万并发 假如网络包的大小都可以控制在8K以下, 假设所有连接的网络都不会拥堵, 或者拥堵时候的总量在8K以下 一个socket的内存占用介于 24K ~ 32K之间, 保守的按照32K算 4G/32K=13.1万并发, 这个在生产环境作为一个纯网络层面的内存消耗, 是可以作为参考的. 假如使用默认配置, 假如所有连接的网络都出现严重拥堵, 不考虑逻辑上的发送队列的占用, 使用默认配置是2M+2M+8+8 ~= 4M 4G/4M=1024并发 ( … 如果考虑到发送队列也拥堵的话 自己脑补. 如果只是为了跑分 为了并发而优化, 没有常驻的逻辑缓冲区 并且socket的网络吞吐量很小并且负载平滑, 把socket buffer size设置系统最低. 那么是 4G/8K = 52.4万并发 这个应该是极限值了.

linux下的epoll有什么作用?

你好,希望我的回答对你有帮助 1. Epoll是何方神圣? Epoll可是当前在Linux下开发大规模并发网络程序的热门人选,Epoll 在Linux2.6内核中正式引入,和select相似,其实都I/O多路复用技术而已,并没有什么神秘的。

其实在Linux下设计并发网络程序,向来不缺少方法,比如典型的Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,以及select模型和poll模型,那为何还要再引入Epoll这个东东呢?那还是有得说说的… 2. 常用模型的缺点 如果不摆出来其他模型的缺点,怎么能对比出Epoll的优点呢。

2.1 PPC/TPC模型 这两种模型思想类似,就是让每一个到来的连接一边自己做事去,别再来烦我。

只是PPC是为它开了一个进程,而TPC开了一个线程。

可是别烦我是有代价的,它要时间和空间啊,连接多了之后,那么多的进程/线程切换,这开销就上来了;因此这类模型能接受的最大连接数都不会高,一般在几百个左右。

2.2 select模型 1. 最大并发数限制,因为一个进程所打开的FD(文件描述符)是有限制的,由FD_SETSIZE设置,默认值是1024/2048,因此Select模型的最大并发数就被相应限制了。

自己改改这个FD_SETSIZE?想法虽好,可是先看看下面吧… 2. 效率问题,select每次调用都会线性扫描全部的FD集合,这样效率就会呈现线性下降,把FD_SETSIZE改大的后果就是,大家都慢慢来,什么?都超时了??!! 3. 内核/用户空间内存拷贝问题,如何让内核把FD消息通知给用户空间呢?在这个问题上select采取了内存拷贝方法。

2.3 poll模型 基本上效率和select是相同的,select缺点的2和3它都没有改掉。

3. Epoll的提升 把其他模型逐个批判了一下,再来看看Epoll的改进之处吧,其实把select的缺点反过来那就是Epoll的优点了。

3.1. Epoll没有最大并发连接的限制,上限是最大可以打开文件的数目,这个数字一般远大于2048, 一般来说这个数目和系统内存关系很大,具体数目可以cat /proc/sys/fs/file-max察看。

3.2. 效率提升,Epoll最大的优点就在于它只管你“活跃”的连接,而跟连接总数无关,因此在实际的网络环境中,Epoll的效率就会远远高于select和poll。

3.3. 内存拷贝,Epoll在这点上使用了“共享内存”,这个内存拷贝也省略了。

4. Epoll为什么高效 Epoll的高效和其数据结构的设计是密不可分的,这个下面就会提到。

首先回忆一下select模型,当有I/O事件到来时,select通知应用程序有事件到了快去处理,而应用程序必须轮询所有的FD集合,测试每个FD是否有事件发生,并处理事件;代码像下面这样: int res = select(maxfd+1, &readfds, NULL, NULL, 120); if(res > 0) { for (int i = 0; i < MAX_CONNECTION; i++) { if (FD_ISSET(allConnection[i], &readfds)) { handleEvent(allConnection[i]); } } } // if(res == 0) handle timeout, res < 0 handle error Epoll不仅会告诉应用程序有I/0 事件到来,还会告诉应用程序相关的信息,这些信息是应用程序填充的,因此根据这些信息应用程序就能直接定位到事件,而不必遍历整个FD 集合。

intres = epoll_wait(epfd, events, 20, 120); for(int i = 0; i < res;i++) { handleEvent(events[n]); } 5. Epoll关键数据结构 前面提到Epoll速度快和其数据结构密不可分,其关键数据结构就是: structepoll_event { __uint32_t events; // Epoll events epoll_data_t data; // User data variable }; typedefunion epoll_data { void *ptr; int fd; __uint32_t u32; __uint64_t u64; } epoll_data_t; 可见epoll_data是一个union结构体,借助于它应用程序可以保存很多类型的信息:fd、指针等等。

有了它,应用程序就可以直接定位目标了。

6. 使用Epoll 既然Epoll相比select这么好,那么用起来如何呢?会不会很繁琐啊…先看看下面的三个函数吧,就知道Epoll的易用了。

int epoll_create(int size); 生成一个Epoll专用的文件描述符,其实是申请一个内核空间,用来存放你想关注的socket fd上是否发生以及发生了什么事件。

size就是你在这个Epoll fd上能关注的最大socket fd数,大小自定,只要内存足够。

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event ); 控制某个Epoll文件描述符上的事件:注册、修改、删除。

其中参数epfd是epoll_create()创建Epoll专用的文件描述符。

相对于select模型中的FD_SET和FD_CLR宏。

int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout); 等待I/O事件的发生;参数说明: epfd:由epoll_create() 生成的Epoll专用的文件描述符; epoll_event:用于回传代处理事件的数组; maxevents:每次能处理的事件数; timeout:等待I/O事件发生的超时值; 返回发生事件数。

相对于select模型中的select函数。

7. 例子程序 下面是一个简单Echo Server的例子程序,麻雀虽小,五脏俱全,还包含了一个简单的超时检查机制,简洁起见没有做错误处理。

参考地址:/sparkliang/article/details/4770655

ManSora:英国CN2 VPS,1核/1GB内存/10GB SSD/1TB流量/100Mbps/KVM,$18.2/月

mansora怎么样?mansora是一家国人商家,主要提供沪韩IEPL、沪日IEPL、深港IEPL等专线VPS。现在新推出了英国CN2 KVM VPS,线路为AS4809 AS9929,可解锁 Netflix,并有永久8折优惠。英国CN2 VPS,$18.2/月/1GB内存/10GB SSD空间/1TB流量/100Mbps端口/KVM,有需要的可以关注一下。点击进入:mansora官方网站地址m...

萤光云(13.25元)香港CN2 新购首月6.5折

萤光云怎么样?萤光云是一家国人云厂商,总部位于福建福州。其成立于2002年,主打高防云服务器产品,主要提供福州、北京、上海BGP和香港CN2节点。萤光云的高防云服务器自带50G防御,适合高防建站、游戏高防等业务。目前萤光云推出北京云服务器优惠活动,机房为北京BGP机房,购买北京云服务器可享受6.5折优惠+51元代金券(折扣和代金券可叠加使用)。活动期间还支持申请免费试用,需提交工单开通免费试用体验...

PIGYun中秋特惠:香港/韩国VPS月付14元起

PIGYun发布了九月份及中秋节特惠活动,提供8折优惠码,本月商家主推中国香港和韩国机房,优惠后最低韩国每月14元/中国香港每月19元起。这是一家成立于2019年的国人商家,提供中国香港、韩国和美国等地区机房VPS主机,基于KVM架构,采用SSD硬盘,CN2+BGP线路(美国为CUVIP-AS9929、GIA等)。下面列出两款主机配置信息。机房:中国香港CPU:1core内存:1GB硬盘:10GB...

epoll为你推荐
mdm.mdm是什么扩展名?ISDNISDN是什么?赶什么用的? 详细点谢谢!图片地址怎么获得图片地址知识库管理系统什么是知识管理云图片华为手机的云照片怎么不见了怎么办丁奇请全面剖析一下黑胡子丁奇这个人物。spawningVC中Error spawning cl.exe错误的解决方法.spawning急救!编好C++程序后(确认无误),再编译时总出现error spawning 是什么意思?是不是系统出了问题民生电商民生电商与传统的电商有什么区别?清除电脑垃圾怎么删除电脑垃圾?
阿里云邮箱登陆首页 主机点评 警告本网站 台湾谷歌网址 本网站服务器在美国 777te cn3 starry cxz 免费的域名 免备案cdn加速 .htaccess windowsserver2008r2 godaddy中文 phpwind论坛 easypanel let dns是什么意思 ddos是什么 主机声音大 更多