epoll

IO模型(epoll)--详解-03

匿名 (未验证) 提交于 2019-12-03 00:05:01
写在前面   epoll是开发linux高性能服务器的必备技术至,epoll本质,是服务端程序员的必须掌握的知识。 七、epoll的原理和流程   本节会以示例和图表来讲解epoll的原理和流程。 创建epoll对象   如下图所示,当某个进程调用epoll_create方法时,内核会创建一个eventpoll对象(也就是程序中epfd所代表的对象)。eventpoll对象也是文件系统中的一员,和socket一样,它也会有等待队列。内核创建eventpoll对象 维护监视列表   创建epoll对象后,可以用epoll_ctl添加或删除所要监听的socket。以添加socket为例,如下图,如果通过epoll_ctl添加sock1、sock2和sock3的监视,内核会将eventpoll添加到这三个socket的等待队列中。添加所要监听的socket 接收数据   当socket收到数据后,中断程序会给eventpoll的“就绪列表”添加socket引用。如下图展示的是sock2和sock3收到数据后,中断程序让rdlist引用这两个socket。给就绪列表添加引用   eventpoll对象相当于是socket和进程之间的中介,socket的数据接收并不直接影响进程,而是通过改变eventpoll的就绪列表来改变进程状态。   当程序执行到epoll_wait时

I/O多路复用

匿名 (未验证) 提交于 2019-12-02 23:51:01
1、使用场景   IO多路复用是指内核一旦发现进程指定的一个或者多个IO条件准备读取,它就通知该进程。IO多路复用适用如下场合:   (1)当客户处理多个描述字时(一般是交互式输入和网络套接口),必须使用I/O复用。   (2)当一个客户同时处理多个套接口时,而这种情况是可能的,但很少出现。   (3)如果一个TCP服务器既要处理监听套接口,又要处理已连接套接口,一般也要用到I/O复用。   (4)如果一个服务器即要处理TCP,又要处理UDP,一般要使用I/O复用。   (5)如果一个服务器要处理多个服务或多个协议,一般要使用I/O复用。   与多进程和多线程技术相比,I/O多路复用技术的最大优势是系统开销小,系统不必创建进程/线程,也不必维护这些进程/线程,从而大大减小了系统的开销。 不同IO模式比较: select poll 移植性好,但单进程监视的文件数过多会性能不佳,不适合用于大并发 select的问题: (1)被监控的fds集合限制为1024 (2)fds集合需要从用户空间拷贝到内核空间 (3)当被监控的fds中某些有数据可读的时候,无法直接从通知中得到有可读事件的fds列表,而需要遍历整个fds来收集 poll使用pollfd结构而不是select的fd_set结构,解决问题(1) 水平触发,边缘触发:通知进程的方式 1. LTģʽ LT(level triggered

【I/O多路复用】epoll系统调用

匿名 (未验证) 提交于 2019-12-02 23:49:02
版权声明:署名,允许他人基于本文进行创作,且必须基于与原先许可协议相同的许可协议分发本文 ( Creative Commons ) 文章目录 【1】epoll相关的系统调用 epoll_create() epoll_ctl() epoll_wait() 【2】代码示例 【1】epoll相关的系统调用 epoll是Linux特有的I/O复用函数。它在实现和使用上与select、poll有很大差异。 首先 , epoll使用一组函数来完成任务 ,而不是单个函数。 其次 , epoll 把用户关心的文件描述符上的事件放在内核里的一个事件表中 ,从而无须像select和poll那样每次调用都要重复传人文件描述符集或事件集。 但是 epoll需要使用一个额外的文件描述符,来唯一标识内核中的这个事件表。 epoll_create() 这个文件描述符使用如下epoll create函数来创建: # include <sys/epoll.h> int epoll_create ( int size ) 其中 size参数现在并不起作用,只是给内核一个提示,告诉它事件表需要多大。 返回值 该函数返回一个文件描述符,用作其他所有epoll系统调用的第一个参数,用来指定要访问的内核事件表。 epoll_ctl() # include <sys/epoll.h> int epoll_ctl ( int

epoll实现多路复用

匿名 (未验证) 提交于 2019-12-02 23:40:02
程序阻塞的过程 假设系统目前运行了三个进程 A B C 进程A正在运行一下socket程序 server = socket . socket () server . bind (( "127.0.0.1" , 1688 )) server . listen () server . accept () 1.系统会创建文件描述符指向一个socket对象 ,其包含了读写缓冲区,已经进行等待队列 2.当执行到accept / recv 时系统会讲进程A 从工作队列中移除 3.将进程A的引用添加到 socket对象的等待队列中 进程的唤醒 1.当网卡收到数据后会现将数据写入到缓冲区 2.发送中断信号给CPU 3.CPU执行中断程序,将数据从内核copy到socket的缓冲区 4.唤醒进程,即将进程A切换到就绪态,同时从socket的等待队列中移除这个进程引用 用select来监控多个socket select的实现思路比较直接 1.先将所有socket放到一个列表中, 2.遍历这个列表将进程A 添加到每个socket的等待队列中 然后阻塞进程 3.当数据到达时,cpu执行中断程序将数据copy给socket 同时唤醒处于等待队列中的进程A为了防止重复添加等待队列 还需要移除已经存在的进程A 4.进程A唤醒后 由于不清楚那个socket有数据,所以需要遍历一遍所有socket列表 缺点: 1

epoll使用详解

匿名 (未验证) 提交于 2019-12-02 23:26:52
本文全文转载于: https://blog.csdn.net/ljx0305/article/details/4065058 1、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,第四个参数是告诉内核需要监听什么事

Nginx工作原理和优化

匿名 (未验证) 提交于 2019-12-02 22:10:10
1. Nginx的模块与工作原理 Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单,仅仅通过查找配置文件将客户端请求映射到一个location block(location是Nginx配置中的一个指令,用于URL匹配),而在这个location中所配置的每个指令将会启动不同的模块去完成相应的工作。 Nginx的模块从结构上分为核心模块、基础模块和第三方模块: 核心模块:HTTP模块、EVENT模块和MAIL模块 基础模块:HTTP Access模块、HTTP FastCGI模块、HTTP Proxy模块和HTTP Rewrite模块, 第三方模块:HTTP Upstream Request Hash模块、Notice模块和HTTP Access Key模块。 用户根据自己的需要开发的模块都属于第三方模块。正是有了这么多模块的支撑,Nginx的功能才会如此强大。 Nginx的模块从功能上分为如下三类。 Handlers(处理器模块)。此类模块直接处理请求,并进行输出内容和修改headers信息等操作。Handlers处理器模块一般只能有一个。 Filters (过滤器模块)。此类模块主要对其他处理器模块输出的内容进行修改操作,最后由Nginx输出。 Proxies (代理类模块)。此类模块是Nginx的HTTP Upstream之类的模块

Linux编程之Epoll高并发

匿名 (未验证) 提交于 2019-12-02 21:59:42
网络上所有资料都说epoll是高并发、单线程、IO重叠服用的首选架构,比select和poll性能都要好,特别是在有大量不活跃连接的情况下。具体原理就不阐述了,下面说说使用。 具有有三个函数: #include <sys/epoll.h> 1、int epoll_create ( int size ); size是epoll要监视的fd的规模。 2、int epoll_ctl ( int epfd, int op, int fd, struct epoll_event *event ); (1)epfd:epoll_create的返回值。 (3)fd:要操作的文件描述符(socket) struct epoll_event { }; events:描述事件类型。events可以是以下几个宏的集合: EPOLLOUT:表示对应的文件描述符可以写; EPOLLERR:表示对应的文件描述符发生错误; EPOLLHUP:表示对应的文件描述符被挂断; EPOLLONESHOT:只监听一次事件,当监听完这次事件之后,如果还需要继续监听这个socket的话,需要再次把这个socket加入到EPOLL队列里。 data成员:其中data.fd常用来装要操作的fd。 typedef union epoll_data { 3、int epoll_wait ( int epfd, struct

Linux Epoll介绍和程序实例

匿名 (未验证) 提交于 2019-12-02 21:59:42
1. Epoll是何方神圣? 其实在Linux下设计并发网络程序,向来不缺少方法,比如典型的Apache模型(Process Per Connection,简称PPC),TPC(Thread PerConnection)模型,以及select模型和poll模型,那为何还要再引入Epoll这个东东呢?那还是有得说说的… 如果不摆出来其他模型的缺点,怎么能对比出Epoll的优点呢。 2.1 PPC/TPC模型 这两种模型思想类似,就是让每一个到来的连接一边自己做事去,别再来烦我。只是PPC是为它开了一个进程,而TPC开了一个线程。可是别烦我是有代价的,它要时间和空间啊,连接多了之后,那么多的进程/线程切换,这开销就上来了;因此这类模型能接受的最大连接数都不会高,一般在几百个左右。 2.2 select模型 2.3 poll模型 基本上效率和select是相同的,select缺点的2和3它都没有改掉。 3. Epoll的提升 把其他模型逐个批判了一下,再来看看Epoll的改进之处吧,其实把select的缺点反过来那就是Epoll的优点了。 4. Epoll为什么高效 Epoll的高效和其数据结构的设计是密不可分的,这个下面就会提到。 首先回忆一下select模型,当有I/O事件到来时,select通知应用程序有事件到了快去处理,而应用程序必须轮询所有的FD集合,测试每个FD是否有事件发生

Linux事件驱动IO中select vs epoll

匿名 (未验证) 提交于 2019-12-02 21:56:30
背景 select 和epoll的背景不同,select是POSIX标准,代码移植性好,epoll是Linux标准,代码可移植性只在Linux操作系统之间。 触发条件 select只支持条件触发(level-triggered),epoll支持条件触发和边缘触发。   条件触发(level-triggered):当条件满足时,发生一个I/O事件。   边缘触发(edge-triggered):当状态改变时,发生一个I/O事件。 条件触发对编码代码的要求低,不容易丢事件,在大流量,高并发的环境下,效率不好,只要有数据没有处理,内核不断的通知你。 边缘触发,代码编写复杂,需要防止丢失事件,容易发生事件丢失的情况。 对文件描述符的处理 select最大支持1024个文件描述符,选择描述符时,遍历所有的描述符才能获取到哪些描述符有事件通知,效率低。 epoll对于描述符事件的选择不是遍历,是事件响应的,描述符上事件来就马上选择出来,不需要遍历整个句柄链表,因此效率非常高。 来源:博客园 作者: 好吧,就是菜菜 链接:https://www.cnblogs.com/shuiyonglewodezzzzz/p/11495161.html

Boost Asio single threaded performance

删除回忆录丶 提交于 2019-12-02 18:29:48
I am implementing custom server that needs to maintain very large number (100K or more) of long lived connections. Server simply passes messages between sockets and it doesn't do any serious data processing. Messages are small, but many of them are received/send every second. Reducing latency is one of the goals. I realize that using multiple cores won't improve performance and therefore I decided to run the server in a single thread by calling run_one or poll methods of io_service object. Anyway multi-threaded server would be much harder to implement. What are the possible bottlenecks?