zoukankan      html  css  js  c++  java
  • nginx事件模块 第四篇

    微信公众号:郑尔多斯
    关注可了解更多的Nginx知识。任何问题或建议,请公众号留言;
    关注公众号,有趣有内涵的文章第一时间送达!

    剧情回顾

    上一篇文章中我们详细介绍了Nginx中事件模块的初始化过程。这里简单的回顾一下:Nginxworker进程启动之后,会首先进行worker的初始化,在初始化过程中将遍历调用所有模块的init_process函数。与Nginx事件机制相关的三个模块中,只有ngx_event_core_module才实现了对应的钩子函数ngx_event_process_init。上一篇文章我们已经比较详细的分析了这篇文章,但是还遗留了几个问题,比如,epoll是如何初始化的,时间定时器是如何初始化的。本篇文章就分析一下epoll是如何初始化的。

    epoll初始化

    首先观察ngx_event_process_init下面的代码:

     1for (m = 0; cycle->modules[m]; m++) {
    2        if (cycle->modules[m]->type != NGX_EVENT_MODULE) {
    3            continue;
    4        }
    5
    6        if (cycle->modules[m]->ctx_index != ecf->use) {
    7            continue;
    8        }
    9
    10        module = cycle->modules[m]->ctx;
    11
    12        if (module->actions.init(cycle, ngx_timer_resolution) != NGX_OK) {
    13            /* fatal */
    14            exit(2);
    15        }
    16
    17        break;
    18    }

    这部分代码就涵盖了epoll的初始化过程,它是如何实现的呢?

    遍历所有的模块,找到我们选择的事件处理模块,本例中就是ngx_epoll,然后调用时间模块的action.init()方法。

    下面我们看一下ngx_epoll的源码:

     1static ngx_event_module_t  ngx_epoll_module_ctx = {
    2    &epoll_name,
    3    ngx_epoll_create_conf,               /* create configuration */
    4    ngx_epoll_init_conf,                 /* init configuration */
    5
    6    {
    7        ngx_epoll_add_event,             /* add an event */
    8        ngx_epoll_del_event,             /* delete an event */
    9        ngx_epoll_add_event,             /* enable an event */
    10        ngx_epoll_del_event,             /* disable an event */
    11        ngx_epoll_add_connection,        /* add an connection */
    12        ngx_epoll_del_connection,        /* delete an connection */
    13#if (NGX_HAVE_EVENTFD)
    14        ngx_epoll_notify,                /* trigger a notify */
    15#else
    16        NULL,                            /* trigger a notify */
    17#endif
    18        ngx_epoll_process_events,        /* process the events */
    19        ngx_epoll_init,                  /* init the events */
    20        ngx_epoll_done,                  /* done the events */
    21    }
    22};

    从代码中可以看到,action.init()对应于ngx_epoll_init(),下面我们分析一下该函数

    ngx_epoll_init

    先看代码:

     1static ngx_int_t
    2ngx_epoll_init(ngx_cycle_t *cycle, ngx_msec_t timer)
    3
    {
    4    ngx_epoll_conf_t  *epcf;
    5
    6    epcf = ngx_event_get_conf(cycle->conf_ctx, ngx_epoll_module);
    7
    8    if (ep == -1) {
    9        ep = epoll_create(cycle->connection_n / 2);
    10
    11        if (ep == -1) {
    12            ngx_log_error(NGX_LOG_EMERG, cycle->log, ngx_errno,
    13                          "epoll_create() failed");
    14            return NGX_ERROR;
    15        }
    16
    17#if (NGX_HAVE_EVENTFD)
    18        if (ngx_epoll_notify_init(cycle->log) != NGX_OK) {
    19            ngx_epoll_module_ctx.actions.notify = NULL;
    20        }
    21#endif
    22
    23#if (NGX_HAVE_FILE_AIO)
    24        ngx_epoll_aio_init(cycle, epcf);
    25#endif
    26
    27#if (NGX_HAVE_EPOLLRDHUP)
    28        ngx_epoll_test_rdhup(cycle);
    29#endif
    30    }
    31
    32    if (nevents < epcf->events) {
    33        if (event_list) {
    34            ngx_free(event_list);
    35        }
    36
    37        event_list = ngx_alloc(sizeof(struct epoll_event) * epcf->events,
    38                               cycle->log);
    39        if (event_list == NULL) {
    40            return NGX_ERROR;
    41        }
    42    }
    43
    44    nevents = epcf->events;
    45
    46    ngx_io = ngx_os_io;
    47
    48    ngx_event_actions = ngx_epoll_module_ctx.actions;
    49
    50#if (NGX_HAVE_CLEAR_EVENT)
    51    ngx_event_flags = NGX_USE_CLEAR_EVENT
    52#else
    53    ngx_event_flags = NGX_USE_LEVEL_EVENT
    54#endif
    55                      |NGX_USE_GREEDY_EVENT
    56                      |NGX_USE_EPOLL_EVENT;
    57
    58    return NGX_OK;
    59}

    这部分代码就是epoll初始化的代码,我们可以清晰的理一下思路:

    • 使用epoll_create()创建一个epoll实例
    • 根据配置文件中events的数量创建对应数量的epoll_event结构体
    • 设置一些全局变量的值,如nevents , ngx_io , ngx_event_actions
    • 这里有一个比较重要的变量就是 ngx_event_flags,这个变量在后面经常使用到,通过调试发现该变量的值为:NGX_USE_CLEAR_EVENT | NGX_USE_GREEDY_EVENT | NGX_USE_EPOLL_EVENT

    喜欢本文的朋友们,欢迎长按下图关注订阅号郑尔多斯,更多精彩内容第一时间送达

    郑尔多斯郑尔多斯
  • 相关阅读:
    在Leangoo里怎么添加,移动列表,修改列表名称?
    在Leangoo里怎么列表示例,插入列表?
    tomcat如何按站点调试本机程序
    ORA-12519, TNS:no appropriate service handler found
    mysql 远程访问
    手机端调试成功笔记
    Cannot find class for bean with name service
    android模拟器不能用键盘
    eclipse使用基础--让toolbar显示自己想要的内容
    mysql解压版安装
  • 原文地址:https://www.cnblogs.com/zhengerduosi/p/10173519.html
Copyright © 2011-2022 走看看