Nginx源码阅读-事件循环的实现

目录

概述

ngx_event.h

ngx_event.c

知识点补充

ngx_connection_t 结构体


概述

Nginx中ngx_event.c主要实现以下功能

  • 事件模块的初始化
  • 事件的添加和删除
  • 事件循环的实现
  • 总结:Nginx中每一个连接都用一个单独的结构体管理起来,每个连接中又有不同的事件处理结构体。然后统一将这些连接交给epoll管理,从而实现连接的快速反应。

Nginx中ngx_event.h主要实现

  • 定义不同类型
  • ngx_event_s结构体,描述事件的数据结构,其中包括处理函数和状态标志
  • 事件模块接口,定义不同事件驱动机制需要实现的函数接口

ngx_event.h

ngx_event_s结构体(Nginx事件处理比如读写的核心数据结构)

  • data:指向与事件相关的数据,一般是指向 ngx_connection_t 结构体的指针。
  • handler:事件处理函数,当事件触发时调用该函数。
  • log:指向日志对象,用于记录事件相关的日志信息。
  • index:事件在事件数组中的索引。

 

重点:事件处理函数(epoll多路转接的实现)

  • 首先定义函数原型,分别有添加事件、删除事件、处理所有事件并定时
  • 其次提供事件模块的接口,该接口用于不同的驱动实现,此处只重点关注epoll的实现
void ngx_event_add(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
void ngx_event_del(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags);
void ngx_process_events_and_timers(ngx_cycle_t *cycle);

 

事件机制的实现

  • Linux下epoll的实现,需要上述图2中ngx_event_module_t定义的接口函数,例如增加删除一个事件
  • 分析ngx_epoll_module结构体(里面是一些epoll函数的声明)

例如EPOLL添加事件函数的实现

 

static ngx_int_t ngx_epoll_add_event(ngx_event_t *ev, ngx_int_t event, ngx_uint_t flags) {
    struct epoll_event ee;
    int op;

    // 设置事件类型
    if (event == NGX_READ_EVENT) {
        ee.events = EPOLLIN | EPOLLET;
    } else if (event == NGX_WRITE_EVENT) {
        ee.events = EPOLLOUT | EPOLLET;
    }

    // 设置事件数据
    ee.data.ptr = (void *) ((uintptr_t) ev | ev->instance);

    // 添加或修改事件
    if (ev->active) {
        op = EPOLL_CTL_MOD;
    } else {
        op = EPOLL_CTL_ADD;
        ev->active = 1;
    }

    if (epoll_ctl(ep, op, ev->fd, &ee) == -1) {
        return NGX_ERROR;
    }

    return NGX_OK;
}

ngx_event.c

初始化事件模块:选择合适数据结构+选择事件驱动机制(例如选择epoll、红黑树等)

添加事件:将一个事件添加到事件驱动机制,例如将事件放到epoll中进行管理

 

 删除事件:将事件从epoll中移除(当然也可以从其他的事件驱动机制中删除)。从内核中移除对该事件的关心。

 

事件循环:调用具体事件模块的事件处理函数,同时调用定时器

  • 获取下一个定时器事件的超时时间
  • 调用具体的事件模块处理函数
  • 更新定时器 

 epoll具体事件处理实现

  • 调用epoll_wait 获取就绪事件:由内核返回有几个监控的事件已经准备继续
  • 遍历所有就绪的事件,然后调用相应的函数对其进行处理

 初始化定时器,Nginx底层使用一个红黑树管理素所有的定时器

 添加定时器中的事件

  • 主要作用是将一个定时器事件添加到定时器的红黑树中
  • 计算定时器事件的触发事件,定时器在特定的时间内被触发
  • 将定时器事件插入到定时器红黑树中

 处理超时事件

  • 获取当前时间
  • 遍历定时器红黑树中多有的节点,找到已经超时的定时器事件
  • 调用定时器事件的处理函数,即预先设定的定时器事件的处理函数

知识点补充

ngx_connection_t 结构体

该结构体主要用于表示网络连接的核心数据结构,其封装了网络连接中所需要的相关信息,即是将连接打包管理了起来。

  • 结构体部分定义分析

具体使用分析

  • 创建连接
    • 客户端连接时,Nginx创建爱一个ngx_connection_t结构体实例,同时对结构体实例初始化 
  • 事件处理函数封装
    • 该结构体中包含了读事件和写事件,当这些事件被触发的时候,调用相应的事件处理函数进行处理
  • 发送数据
    • 需要向客户端发送数据的时候,通过send函数指针发送

分析事件和连接如何关联

  • ngx_event_t结构体中拥有一个指向ngx_connection_t的指针

 新连接到来后,Nginx创建一个ngx_connnection_t的实例,然后在使用完成后又会关闭该连接

  • 创建连接
  • 释放连接

  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值