(转)浅析epoll-为何多路复用I/O要使用epoll
原文地址:http://www.cppfans.org/1417.html
浅析epoll-为何多路复用I/O要使用epoll
现如今,网络通讯中用epoll(linux)和IOCP(windows)几乎是大家津津乐道的东西,不为别的,就因为高效,所以大家喜欢用。IOCP的基础东西已经讲过了,可翻阅《IOCP浅析》 《IOCP浅析[二]——IOCP出现的意义和函数接口》.
什么是epoll?
epoll是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率,因为它会复用文件描述符集 合来传递结果而不用迫使开发者每次等待事件之前都必须重新准备要被侦听的文件描述符集合,另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符 集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的电平触发 (Level Triggered)外,还提供了边沿触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。Linux2.6内核中对/dev/epoll设备的访问的封装(system epoll)。
这个使我们开发网络应用程序更加简单,并且更加高效。
为什么要使用epoll?
同样,我们在linux系统下,影响效率的依然是I/O操作,linux提供给我们select/poll/epoll等多路复用I/O方式(kqueue暂时没研究过),为什么我们对epoll情有独钟呢?原因如下:
1.文件描述符数量的对比。
epoll并没有fd(文件描述符)的上限,它只跟系统内存有关,我的2G的ubuntu下查看是20480个,轻松支持20W个fd。可使用如下命令查看:
| cat /proc/sys/fs/file-max | 
再来看select/poll,有一个限定的fd的数量,linux/posix_types.h头文件中
| #define __FD_SETSIZE 1024 | 
2.效率对比。
当然了,你可以修改上述值,然后重新编译内核,然后再次写代码,这也是没问题的,不过我先说说select/poll的机制,估计你马上会作废上面修改枚举值的想法。
select/poll会因为监听fd的数量而导致效率低下,因为它是轮询所有fd,有数据就处理,没数据就跳过,所以fd的数量会降低效率;而epoll只处理就绪的fd,它有一个就绪设备的队列,每次只轮询该队列的数据,然后进行处理。(先简单讲一下,第二篇还会详细讲解)
3.内存处理方式对比。
不管是哪种I/O机制,都无法避免fd在操作过程中拷贝的问题,而epoll使用了mmap(是指文件/对象的内存映射,被映射到多个内存页上),所以同一块内存就可以避免这个问题。
btw:TCP/IP协议栈使用内存池管理sk_buff结构,你还可以通过修改内存池pool的大小,毕竟linux支持各种微调内核。
epoll的工作方式
epoll分为两种工作方式LT和ET。
LT(level triggered) 是默认/缺省的工作方式,同时支持 block和no_block socket。这种工作方式下,内核会通知你一个fd是否就绪,然后才可以对这个就绪的fd进行I/O操作。就算你没有任何操作,系统还是会继续提示fd已经就绪,不过这种工作方式出错会比较小,传统的select/poll就是这种工作方式的代表。
ET(edge-triggered) 是高速工作方式,仅支持no_block socket,这种工作方式下,当fd从未就绪变为就绪时,内核会通知fd已经就绪,并且内核认为你知道该fd已经就绪,不会再次通知了,除非因为某些操作导致fd就绪状态发生变化。如果一直不对这个fd进行I/O操作,导致fd变为未就绪时,内核同样不会发送更多的通知,因为only once。所以这种方式下,出错率比较高,需要增加一些检测程序。
LT可以理解为水平触发,只要有数据可以读,不管怎样都会通知。而ET为边缘触发,只有状态发生变化时才会通知,可以理解为电平变化。
如何使用epoll?
使用epoll很简单,只需要
| #include <sys/epoll.h> | 
有三个关键函数:
int epoll_create(int size);
int epoll_ctl(int epfd, int op, int fd, struct epoll_events* event);
int epoll_wait(int epfd, struct epoll_event* events, int maxevents, int timeout);
当然了,不要忘记关闭函数.
============分割线==============
这篇就讲到这里了,下面两篇主要是函数介绍,效率分析,例子。
(转)浅析epoll-为何多路复用I/O要使用epoll的更多相关文章
- I/O模型系列之五:IO多路复用 select、poll、epoll
		IO多路复用之select.poll.epoll IO多路复用:通过一种机制,一个进程可以监视多个描述符,一旦某个描述符就绪(一般是读就绪或者写就绪),能够通知程序进行相应的读写操作. 应用:适用于针 ... 
- epoll——IO多路复用选择器
		上上篇博客讲的套接字,由于其阻塞性而导致一个服务端同一时间只能与一个客户端连接.基于这个缺点,在上篇博客我们将其设置为非阻塞实现了一个服务端同一时间可以与多个客户端相连,即实现了并发,但其同样留下了一 ... 
- epoll IO多路复用(异步阻塞AIO)
		epoll的异步阻塞(AIO): 用户线程创建epoll后,其实是内核线程负责扫描 fd 列表(在网络服务器上可以是socket,socket在创建后返回的也是文件描述符),并填充事件链表.但是,并不 ... 
- #include <sys/epoll.h>  epoll - I/O event notification facility 服务器端  epoll(7) - Linux manual page http://www.man7.org/linux/man-pages/man7/epoll.7.html
		epoll使用详解(精髓) - Boblim - 博客园 https://www.cnblogs.com/fnlingnzb-learner/p/5835573.html epoll使用详解(精髓) ... 
- IO模型之IO多路复用 异步IO select poll epoll 的用法
		IO 模型之 多路复用 IO 多路复用IO IO multiplexing 这个词可能有点陌生,但是如果我说 select/epoll ,大概就都能明白了.有些地方也称这种IO方式为 事件驱动IO ( ... 
- IO多路复用 select、poll、epoll
		什么是IO多路复用 在同一个线程里面, 通过拨开关的方式,来同时传输多个(socket)I/O流. 在英文中叫I/O multiplexing.这里面的 multiplexing 指的其实是在单个线程 ... 
- 浅谈Python-IO多路复用(select、poll、epoll模式)
		1. 什么是IO多路复用 在传统socket通信中,存在两种基本的模式, 第一种是同步阻塞IO,其线程在遇到IO操作时会被挂起,直到数据从内核空间复制到用户空间才会停止,因为对CPython来说,很多 ... 
- 浅析I/O模型-select、poll、epoll
		I/O流 概念 (1)c++中将数据的输入输出称之为流(stream),在c++中,流被定义为类,成为流类(stream class),其定义的对象为流对象. (2)文件,套接字(socket),管道 ... 
- epoll—IO多路复用
		1.在socket.listen()后创一个epoll对象 epoll = select.epoll() 2.将server_socket注册到epoll中 epoll.regist ... 
随机推荐
- [LC] 238. Product of Array Except Self
			Given an array nums of n integers where n > 1, return an array output such that output[i] is equ ... 
- SpringMVC中Interceptor和Filter区别
			Interceptor 主要作用:拦截用户请求,进行处理,比如判断用户登录情况,权限验证,主要针对Action请求进行处理.是通过HandlerInterceptor 实现的. 配置如下: <m ... 
- selenium ide几个版本和对应的firefox版本
			最近安装selenium ide折腾了好久,可能是目前还不太熟悉自动化脚本录制的一些知识. 通过最新版firefox59安装的selenium ide 3.0.2录制的脚本不能导出.于是下载了低版本的 ... 
- Spark和Hadoop MapReduce之间的比较
			关于两者的讨论文章: https://www.zhihu.com/question/26568496 http://blog.jobbole.com/97150/ 文章通过多个角度对两者进行对比,根据 ... 
- (三)mybatis级联的实现
			mybatis级联的实现 开篇 级联有三种对应关系: 1.一对一(association):如学号与学生 2.一对多(collection):如角色与用户 3.多对多(discri ... 
- Django中加载static无法成功的解决方法
			我试着进入/admin/ 结果它的/static/ 能够正常找到目标文件…真是日了哈*奇了. 我的link标签href=/static/…. 并没有什么问题 试着在urls中加入下面代码,但是没什么用 ... 
- html解析过程
			Web页面运行在各种各样的浏览器当中,浏览器载入.渲染页面的速度直接影响着用户体验 简单地说,页面渲染就是浏览器将html代码根据CSS定义的规则显示在浏览器窗口中的这个过程.先来大致了解一下浏览器都 ... 
- OSX安装Mysql8.0
			OSX下MySQL的安装非常方便,可以通过官网的dmg包进行安装,也可通过brew进行安装.以下介绍如何通过brew如何安装MySQL. 0X00.安装前的准备 既然要通过brew安装,那么就需要确保 ... 
- flutter 白板工具Twitter IconFacebook Icon
			flutter 白板工具 Categories: flutter 平常桌面上都放着一些草稿纸,因为经常要整理思路.画画草图啥的.这不是电子时代嘛,就觉得在手机.pad上也可以这样写写画画,我看了有很多 ... 
- Docker Swarm和Kubernetes在大规模集群中的性能比较
			Contents 这篇文章主要针对Docker Swarm和Kubernetes在大规模部署的条件下的3个问题展开讨论.在大规模部署下,它们的性能如何?它们是否可以被批量操作?需要采取何种措施来支持他 ... 
