nginx中的事件响应机制(以epoll为例)
来源:互联网 发布:考勤数据 编辑:程序博客网 时间:2024/05/09 05:08
一.nginx中提供的事件驱动如何实现?
在sys/epoll.h中
1、epoll_create函数
函数声明:int epoll_create(int size)
该 函数生成一个epoll专用的文件描述符。它其实是在内核申请一空间,用来存放你想关注的socket fd上是否发生以及发生了什么事件。size就是你在这个epoll fd上能关注的最大socket fd数。随你定好了。只要你有空间。可参见上面与select之不同
2、epoll_ctl函数
函数声明:int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event)
该函数用于控制某个epoll文件描述符上的事件,可以注册事件,修改事件,删除事件。
3、epoll_wait函数
函数声明:int epoll_wait(int epfd,struct epoll_event * events,int maxevents,int timeout)
该函数用于轮询I/O事件的发生;
在ngx_epoll_epoll_module.c中的函数ngx_epoll_add_event等调用以上几个函数来将文件描述符事件添加到epoll事件监听中去(为何在nginx中有一个空的epoll_ctl等函数???)。
那么这个添加的过程是怎么走的呢,nginx如何将文件描述符事件加入到epoll事件监听中去的呢?
如下这样处理
在Ngx_epoll_module.c中定义一个事件处理模块结构
typedef struct {//事件模块 的名称 ngx_str_t *name;//在解析配置前,这个回调方法用于创建存储配置项参数的结构体 void *(*create_conf)(ngx_cycle_t *cycle);//在解析配置项后,init_conf方法会被调用,用以综合处理当前事件模块感兴趣的所有配置项 char *(*init_conf)(ngx_cycle_t *cycle, void *conf);//对于事件驱动机制,每个事件模块需要实现的10个抽象方法 ngx_event_actions_t actions;} ngx_event_module_t;其中ngx_event_actions_t结构体的定义如下:typedef struct {//添加事件方法,负责将感兴趣的事件添加到操作系统提供的事件驱动机制中(如epoll,kqueue)//这样,在事件发生后,可以调用下面的process_events时或取这个事件 ngx_int_t (*add)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);/*删除事件方法,将已存在于事件驱动机制中的事件移除,以后再发生这样的事件调用process_events也无法获取事件*/ ngx_int_t (*del)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);/*启用一个事件,目前事件框架不会调用这个方法,大部分事件驱动模块对于该事件的实现都是与上面的add方法一致*/ ngx_int_t (*enable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);/*禁用一个事件,目前事件框架不会调用这个方法,大部分事件驱动模块对于该事件的实现都是与上面的del方法一致*/ ngx_int_t (*disable)(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);//向事件驱动机制中添加一个连接,这意味着连接上的读写事件都添加到事件驱动机制中 ngx_int_t (*add_conn)(ngx_connection_t *c);//从事件驱动中移除一个连接的读写事件 ngx_int_t (*del_conn)(ngx_connection_t *c, ngx_uint_t flags); ngx_int_t (*process_changes)(ngx_cycle_t *cycle, ngx_uint_t nowait);//在正常的工作中,将通过调用这个函数来处理事件,//在ngx_process_events_and_timers方法中调用,它是处理分发事件的核心 ngx_int_t (*process_events)(ngx_cycle_t *cycle, ngx_msec_t timer, ngx_uint_t flags);//初始化事件驱动模块 ngx_int_t (*init)(ngx_cycle_t *cycle, ngx_msec_t timer);//退出事件驱动模块前调用的方法 void (*done)(ngx_cycle_t *cycle);} ngx_event_actions_t;
然后用这个类型定义一个变量来添加这些处理函数
ngx_event_module_t ngx_epoll_module_ctx = { &epoll_name, ngx_epoll_create_conf, /* create configuration */ ngx_epoll_init_conf, /* init configuration */ { ngx_epoll_add_event, /* add an event */ ngx_epoll_del_event, /* delete an event */ ngx_epoll_add_event, /* enable an event */ ngx_epoll_del_event, /* disable an event */ ngx_epoll_add_connection, /* add an connection */ ngx_epoll_del_connection, /* delete an connection */ NULL, /* process the changes */ ngx_epoll_process_events, /* process the events */ ngx_epoll_init, /* init the events */ ngx_epoll_done, /* done the events */ }};
在ngx_event_core_module核心的事件模块中有如下定义
ngx_module_t ngx_event_core_module = { NGX_MODULE_V1, &ngx_event_core_module_ctx, /* module context */ ngx_event_core_commands, /* module directives */ NGX_EVENT_MODULE, /* module type */ NULL, /* init master */ ngx_event_module_init, /* init module */ ngx_event_process_init, /* init process */ NULL, /* init thread */ NULL, /* exit thread */ NULL, /* exit process */ NULL, /* exit master */ NGX_MODULE_V1_PADDING};
其中ngx_event_process_init函数是在初始化进程时候调用
1.在ngx_event_process_init这个函数中,使用了如下语句
module->actions.init(cycle, ngx_timer_resolution)用这个来调用ngx_epoll_module_ctx 这个结构中定义init来调用ngx_epoll_init这个回调函数
在ngx_epoll_init这个函数中:通过ngx_event_actions = ngx_epoll_module_ctx.actions;将这些回调函数赋给全局变量ngx_event_actions.
2.在ngx_event_process_init这个函数中,还使用ngx_add_event(rev, 0, NGX_IOCP_ACCEPT),通过宏定义#define ngx_add_event ngx_event_actions.add等来将文件描述符的事件加入到epoll事件监听中去。
事件发生后,nginx如何处理事件?
process_events 在epoll模式中所对应的ngx_epoll_process_events函数是事件发生后处理的一个函数
处理过程基本是判断事件类别,如if(revents & EPOLLOUT) && wev->active),再根据不同的消费模块调用不同的处理函数wev->handler。
例如
http模块中,通过ngx_http_commands中设置的ngx_http_block函数
ngx_http_block函数中调用ls->handler = ngx_http_init_connection;设置ngx_listening_s监听的处理函数。
ngx_http_init_connection;函数中再调用rev->handler = ngx_http_init_request; c->write->handler = ngx_http_empty_handler;来设置文件描述符的处理函数,分别是ngx_http_init_request读事件函数和ngx_http_empty_handler写事件函数
在添加ngx_connection_s的文件描述符的事件监听过程,添加之后listening监听的事件是否被一同添加?(如何测试?)
- nginx中的事件响应机制(以epoll为例)
- 文章6:Nginx中的Epoll事件处理机制
- 文章6:Nginx中的Epoll事件处理机制
- 以ontouch为例说明android事件发送机制
- 以按键事件为例阐述消息传递机制
- Java回调机制(以Android事件监听器为例)
- Nginx学习之七-模块ngx_epoll_module详解(epoll机制在nginx中的实现)
- Nginx学习之七-模块ngx_epoll_module详解(epoll机制在nginx中的实现)
- Nginx事件处理(epoll)
- nginx事件 epoll
- nginx的epoll事件
- Windows Phone中的路由事件-以ListBox控件为例
- epoll事件机制简介
- 3. android响应事件的四种方法(以onclick为例子)
- 以自定义布局为Item的GridView不响应事件
- Android中的内部类(以View的点击事件为例)
- Java的内存分配机制以及变量在内存中的分配(以String为例)
- 【Nginx】epoll事件驱动模块
- STM32再学习――启动流程分析
- 2032. 数字游戏 (Standard IO)
- gcd使用block注意事项
- 面试问题关于cocos-js的优化问题
- winhex万能恢复磁盘数据
- nginx中的事件响应机制(以epoll为例)
- 基于SSH实现管理系统之框架整合篇 3-1 创建项目引入jar包
- 2548. 【NOIP2011模拟9.4】最大正方形 (Standard IO)
- Android之NDK开发
- 【题解】QDUOJ.94.ltwy的比特绷板键盘
- ——字符串最后一个单词的长度
- html5音频和视频
- VMware8 键盘bug
- 《Oracle SQL优化基础》之索引