Nginx源码分析--epoll模块

Nginx采用epoll模块实现高并发的网络编程,现在对Nginx的epoll模块进行分析。

定义在src/event/modules/ngx_epoll_module.c中

1. epoll_create.

int epoll_create(int size);

创建一个epoll的文件描述符,参数size告诉内核这个监听的数目共有多大。

2. epoll_ctl.

int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event);

epoll的事件注册函数。

  • epfd:epoll_create返回值
  • op: EPOLL_CTL_ADD 注册新的fd到epfd中;EPOLL_CTL_MOD 修改已经注册的fd的监听事件;EPOLL_CTL_DEL 从epfd中删除一个fd.
  • fd: 需要监听的文件描述符。
  • event:告诉内核需要监听什么事件。EPOLLIN  可以读(包括对端Socket正常关闭);EPOLLOUT 可以写;EPOLLPRI有紧急的数据可读(有带外数据OOB到来,TCP中的URG包);EPOLLERR该文件描述符发生错误;EPOLLHUP该文件描述符被挂断;EPOLLET 将epoll设置为边缘触发(Edge Triggered)模式;EPOLLONESHOT只监听一次事件,监听完之后,如果还想监听需要再次把该文件描述符加入到epoll队列中。

3. epoll_wait.

int epoll_wait(int epfd, struct epoll_event *events, int nevents, int timeout);

等待事件的产生.

  • 参数events用来表示从内核得到事件的集合,当epoll_wait这个函数操作成功之后,events里面将储存所有的读写事件。
  • 参数nevents是当前要监听的所有事件数/句柄数(nevents不能大于size)
  • 参数timeout是超时时间(毫秒)

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

4. epoll关键数据结构.

struct epoll_event {
    uint32_t      events;   //epoll events
    epoll_data_t  data;   // user data variable
};
typedef union epoll_data {
    void         *ptr;
    int           fd;
    uint32_t      u32;
    uint64_t      u64;
} epoll_data_t;

其中,epoll_data是一个联合体,借助于它应用程序可以保存很多类型的信息:fd、指针等等。有了它,应用程序就可以直接定位目标了。

5. epoll程序框架:

    for( ; ; )
    {
        nfds = epoll_wait(epfd,events,20,500);
        for(i=0;i<nfds;++i)
        {
            if(events[i].data.fd==listenfd) //有新的连接
            {
                connfd = accept(listenfd,(sockaddr *)&clientaddr, &clilen); //accept这个连接
                ev.data.fd=connfd;
                ev.events=EPOLLIN|EPOLLET;
                epoll_ctl(epfd,EPOLL_CTL_ADD,connfd,&ev); //将新的fd添加到epoll的监听队列中
            }
            else if( events[i].events&EPOLLIN ) //接收到数据,读socket
            {
                n = read(sockfd, line, MAXLINE)) < 0    //读
                ev.data.ptr = md;     //md为自定义类型,添加数据
                ev.events=EPOLLOUT|EPOLLET;
                epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);//修改标识符,等待下一个循环时发送数据,异步处理的精髓
            }
            else if(events[i].events&EPOLLOUT) //有数据待发送,写socket
            {
                struct myepoll_data* md = (myepoll_data*)events[i].data.ptr;    //取数据
                sockfd = md->fd;
                send( sockfd, md->ptr, strlen((char*)md->ptr), 0 );        //发送数据
                ev.data.fd=sockfd;
                ev.events=EPOLLIN|EPOLLET;
                epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev); //修改标识符,等待下一个循环时接收数据
            }
            else
            {
                //其他的处理
            }
        }
    }
时间: 2024-08-26 05:14:33

Nginx源码分析--epoll模块的相关文章

nginx源码分析之模块初始化

在nginx启动过程中,模块的初始化是整个启动过程中的重要部分,而且了解了模块初始化的过程对应后面具体分析各个模块会有事半功倍的效果.在我看来,分析源码来了解模块的初始化是最直接不过的了,所以下面主要通过结合源码来分析模块的初始化过程. 稍微了解nginx的人都知道nginx是高度模块化的,各个功能都封装在模块中,而各个模块的初始化则是根据配置文件来进行的,下面我们会看到nginx边解析配置文件中的指令,边初始化指令所属的模块,指令其实就是指示怎样初始化模块的. 模块初始化框架 模块的初始化主要

nginx源码分析——event模块

源码:nginx 1.12.0 一.简介 nginx是一款非常受欢迎的软件,具备高性能.模块化可定制的良好特性.之前写了一篇nginx的http模块分析的文章,主要对http处理模块进行了分析讲解,同时也涉及了nginx模块化的内容.至于nginx高性能的原因,希望能够在在这篇文章中就自己对于这方面的理解给大家分享一下. nginx的event处理模型包含两个方面:高效的IO处理函数,事件的异步处理(可选的线程池). 二.IO复用函数 nginx中包含epoll.poll.select.devp

nginx源码分析——http模块

     源码:nginx 1.12.0   一.nginx http模块简介 由于nginx的性能优势,现在已经有越来越多的单位.个人采用nginx或者openresty.tengine等衍生版来作为WEB服务器.负载均衡服务器.安全网关来使用.在这些场景下,依赖的就是nginx的http模块,nginx的设计者采用模块化的设计思路,允许用户在http请求处理的各个阶段添加自己设计的模块来实现自己的一些逻辑,扩充一些功能. 二.http模块功能介绍 http模块的丰富功能其实是由一个个http

nginx源码分析--事件模块 &amp; 琐碎

通过HUP信息使得NGINX实现重新读取配置文件,使用USR2信号使得NGINX实现平滑升级. 在nginx中有模块这么一说,对外所有的模块都是ngx_module_t类型,这个结构体作为所有模块的通用接口,它只定义了init_master.init_module.init_process.init_thread.exit_thread.exit_process.exit_master这7个回调方法,(其实init_master.init_thread.exit_thread这3个方法目前都没有

Nginx源码分析—架构设计思想

Nginx源码分析-架构设计思想 我任务nginx的源码可以分为三个部分,一个是在ngx_init_cycle之前,这个也算是为了重新启动nginx而准备的代码,比如说在这个时候可以接受外部的信号,也可以保存传递的参数,等等,当然在以后的函数中也考虑了是否正在重启nginx. 至于ngx_init_cycle这个函数,是一个很庞大的函数,在这个函数中可以看到调用了各个模块的钩子函数,这里又设计到了nginx结构体的使用,比如所有的模块都是ngx_module_t这个结构体,但是这个结构体中的ct

nginx源码分析--nginx模块解析

nginx的模块非常之多,可以认为所有代码都是以模块的形式组织,这包括核心模块和功能模块,针对不同的应用场合,并非所有的功能模块都要被用到,附录A给出的是默认configure(即简单的http服务器应用)下被连接的模块,这里虽说是模块连接,但nginx不会像apache或lighttpd那样在编译时生成so动态库而在程序执行时再进行动态加载,nginx模块源文件会在生成nginx时就直接被编译到其二进制执行文件中,所以如果要选用不同的功能模块,必须对nginx做重新配置和编译.对于功能模块的选

nginx源码分析--模块分类

ngx-modules Nginx 主要的模块大致可以分为四类: handler – 协同完成客户端请求的处理.产生响应数据.比如模块, ngx_http_rewrite_module, ngx_http_log_module, ngx_http_static_module. filter – 对 handler 产生的响应数据做各种过滤处理.比如模块, ngx_http_not_modified_filter_module, ngx_http_header_filter_module. ups

[nginx] nginx源码分析--健康检查模块锁分析

健康检查模块 见前文:[nginx] nginx源码分析--健康检查模块 其中有一张框架图, 接下来的内容,将会利用到这个图中的内容. [classic_tong @ https:////www.cnblogs.com/hugetong/p/12274125.html ]  描述 我们知道nginx是多进程的,每个进程都保存了相同的配置.但是实际上, 并不需要每一个进程对每一个后端服务器进行. 于是健康检查模块在这里需要一个进程间同步机制,用来协商哪一个进程对 哪一个后端服务器进行检查. 接下来

Nginx源码分析:3张图看懂启动及进程工作原理

编者按:高可用架构分享及传播在架构领域具有典型意义的文章,本文由陈科在高可用架构群分享.转载请注明来自高可用架构公众号「ArchNotes」.   导读:很多工程师及架构师都希望了解及掌握高性能服务器开发,阅读优秀源代码是一种有效的方式,nginx 是业界知名的高性能 Web 服务器实现,如何有效的阅读及理解 nginx?本文用图解的方式帮助大家来更好的阅读及理解 nginx 关键环节的实现.   陈科,十年行业从业经验,曾在浙江电信.阿里巴巴.华为.五八同城任开发工程及架构师等职,目前负责河狸