epoll的最大好处在于他不会随着被监控描述符的数目的增长而导致效率极致下降。

select是遍历扫描来判断每个描述符是否有事件发生,当监控的描述付越多时,时间消耗就越多,并且由于系统的限制select最多可以监控1024个描述符。

epoll监控的描述符的数目很大,并且epoll对描述符的响应是触发的,即当有描述符有时间发生会有触发。

epoll模型有三个函数

epoll_create(int size);

epoll_wait(int epollfd,struct epoll_event *events,int maxevent,int timeout);

epoll_ctl(int epollfd,int op,struct epoll_event *events);

epoll_create(int size) 是创建size大小的文件描述符

epoll_wait()是用来等待事件的发生

epoll_ctl()是用来向内核注册,删除,修改一个文件描述符的

epoll模型有两种触发方式:一种是边缘触发,一种是水平触发。

eg:

1.进程A将通过pipe P的读端向描述符为fd以边缘触发加到自己的epoll监控里面,并用epoll_wait()等待事件发生

2.进程B往P中写2KB的数据;

3.进程A的描述符fd触发可读事件,因此epoll_wait()函数调用返回。

4.进程A从描述符fd上读取1KB的数据。

5.进程A调用epoll_wait()数据

根据边缘触发的特点:即使pipe P中还有1KB的数据可读,但是并不会触发可读事件,

6.进程B往P中写了2KB的数据

因为此时又有客户端发出请求,即监听套接口上又有新的数据到达,epoll_wait()函数会捕获fd上的可读事件。

解决方法是在ngx_http_read_request_header()函数,在开头加入return NGX_AGAIN 这样让Nginx不读走数据,在写数据的时候,或触发Nginx再次捕获可读信号。

测试代码:

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h> int main(int srgc,char *const *argv)
{
int sockfd;
if((sockfd = socket(AF_INET,SOCK_STREAM,)) == -)
{
fprintf(stderr,"socket fail:%s\n",strerror(errno));
return -;
}
struct sockaddr_in server;
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons();
if(!inet_aton("192.168.1.1",&server.sin_addr))
{
fprintf(stderr,"Bad address %s\n",strerror(errno));
close(sockfd);
return -;
}
if(connect(sockfd,(struct sockaddr*)&server,sizeof(struct sockaddr)) == -)
{
printf(stderr,"connect fail,%s\n",strerror(errno));
close(sockfd);
return -;
}
write(sockfd,"test1",sizeof("test1"));
write(sockfd,"test2",sizeof("test2"));
close(sockfd);
return ;
}

使用边缘触发方式的epoll模型:

1.用于非阻塞文件描述符:即把待加入到epoll模型里的描述符都设置为no-block

2.只有当read()或write()返回EAGAIN,或者read()/write()读到/写到的数据长度小于请求的数据长度时,才需要挂起等待下一个时间的到来,否则会出现错误

Nginx事件管理机制-epoll的更多相关文章

  1. Nginx事件管理之epoll模块

    1. epoll 原理 假设有 100 万用户同时与一个进程保持着 TCP 连接,而每一时刻只有几十个或几百个 TCP 连接时活跃的(接收到 TCP 包),也就是说,在每一时刻,进程只需要处理这 10 ...

  2. Nginx事件管理之概念描述

    1. Nginx事件管理概述 首先,Nginx定义了一个核心模块ngx_events_module,这样在Nginx启动时会调用ngx_init_cycle方法解析配置项,一旦在 nginx.conf ...

  3. Nginx事件管理之事件处理流程

    1. 概述 事件处理要解决的两个问题: "惊群" 问题,即多个 worker 子进程监听相同端口时,在 accept 建立新连接时会有争抢,引发不必要的上下文切换, 增加系统开销. ...

  4. Nginx事件管理之ngx_event_core_module模块

    1. 概述 ngx_event_core_module 模块是一个事件类型的模块,它在所有事件模块中的顺序是第一位.它主要完成以下两点任务: 创建连接池(包括读/写事件): 决定究竟使用哪些事件驱动机 ...

  5. Nginx事件管理之定时器事件

    1. 缓存时间 1.1 管理 Nginx 中的每个进程都会单独地管理当前时间.ngx_time_t 结构体是缓存时间变量的类型: typedef struct { /* 格林威治时间1970年1月1日 ...

  6. Nginx事件管理之核心模块ngx_events_module

    1. ngx_events_module核心模块的功能介绍 ngx_events_module 模式是一个核心模块,它的功能如下: 定义新的事件类型 定义每个事件模块都需要实现的ngx_event_m ...

  7. jquery技巧之让任何组件都支持类似DOM的事件管理

    本文介绍一个jquery的小技巧,能让任意组件对象都能支持类似DOM的事件管理,也就是说除了派发事件,添加或删除事件监听器,还能支持事件冒泡,阻止事件默认行为等等.在jquery的帮助下,使用这个方法 ...

  8. nginx 事件机制原理

    事件驱动模型是Nginx服务器保障完整功能和具有良好性能的重要机制之一. 事件驱动模型概述 实际上,事件驱动并不是计算机编程领域的专业词汇,它是一种比较古老的响应事件的模型,在计算机编程.公共关系.经 ...

  9. nginx&http 第三章 ngx 事件event accept epoll /init

    tcp 三次握手成功后,listen fd  可读,在process_event_timer 中调用rev->handler(rev)处理: 其回调函数为: ngx_event_accept / ...

随机推荐

  1. POJ.1287 Networking (Prim)

    POJ.1287 Networking (Prim) 题意分析 可能有重边,注意选择最小的边. 编号依旧从1开始. 直接跑prim即可. 代码总览 #include <cstdio> #i ...

  2. UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用)

    UVA.12096 The SetStack Computer ( 好题 栈 STL混合应用) 题意分析 绝对的好题. 先说做完此题的收获: 1.对数据结构又有了宏观的上的认识; 2.熟悉了常用STL ...

  3. SpringBoot-配置文件属性注入-3种方式

    配置文件: datasource.username = admin datasource.url = /hello/world 方式一: @Value 前提: <!-- JavaBean处理工具 ...

  4. JSP页面中的Meta标签详解

    Meta标签详解 相信大家在平时开发中最常接触的页面就是html和jsp了,可在这两个页面中有一个Meta标签你天天都会看见,可是你真的了解这个标签的一些其他用处吗?今天给大家介绍一些该标签的其他应用 ...

  5. 在局域网中基于Windows文件共享的git环境搭建

    本文的思想是在局域网中用一台电脑作为服务器,在其中建立一个文件夹,作为总的公开版本库.然后将这个文件夹共享,使其他客户机都可以访问,从而进行代码的管理. 一.下载安装文件 1.git核心: git-f ...

  6. TCP的连接(三次握手)和释放(四次挥手)

    1 http都设置哪些header? http协议规定:一个完整的客户端发送给服务端的HTTP请求包括: (1)请求行:包括了请求方法.请求资源路径.HTTP协议版本,eg:GET/Server/im ...

  7. 工作中常用的Linux命令(不断更新中)

    最近工作中用到linux命令,简单总结如下: 1. pwd 查看当前所在的文件路径 2. cd 切换目录 cd .. 切换到上一级目录 3. ls 列出当前文件路径下的所有文件和文件夹 4. ll 是 ...

  8. mysql的IFNULL()函数FLOOR(),ROUND()函数

    用法说明 1 IFNULL(expr1,expr2) 如果 expr1 不是 NULL,IFNULL() 返回 expr1,否则它返回 expr2. IFNULL()返回一个数字或字符串值,取决于它被 ...

  9. HDU 4576 DP

    Robot Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)Total Sub ...

  10. lnmp环境不支持require 解决方法

    lnmp环境配置: 3处改动地方---->排查过程: 从phpinfo.php中查找php.ini-----所在位置 /usr/local/php/etc/php.ini 1.display_e ...