久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      講解nginx事件模塊的實現(xiàn)細(xì)節(jié)

      在《關(guān)于nginx事件模塊結(jié)構(gòu)體的詳解》這篇文章中,我們講解nginx的事件模塊的整體工作流程,并且著重講解了組織事件模塊的各個方法的作用,本文則主要圍繞這整個流程,從源碼的角度講解nginx事件模塊的實現(xiàn)細(xì)節(jié)。

      講解nginx事件模塊的實現(xiàn)細(xì)節(jié)

      1. ngx_events_block()—-events配置塊解析

      nginx在解析nginx.conf配置文件時,如果當(dāng)前解析的配置項名稱為events,并且是一個配置塊,則會調(diào)用ngx_events_block()方法解析該配置塊,如下是該方法的源碼:

      static char * ngx_events_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {   char *rv;   void ***ctx;   ngx_uint_t i;   ngx_conf_t pcf;   ngx_event_module_t *m;   // 如果存儲事件模塊配置數(shù)據(jù)的配置項不為空,說明已經(jīng)解析過配置項了,因而直接返回   if (*(void **) conf) {     return "is duplicate";   }   // 這里主要是計算event模塊的個數(shù),并且將各個event模塊的相對順序標(biāo)記在了該模塊的ctx_index屬性中   ngx_event_max_module = ngx_count_modules(cf->cycle, NGX_EVENT_MODULE);   // 創(chuàng)建一個存儲配置項數(shù)組的指針   ctx = ngx_pcalloc(cf->pool, sizeof(void *));   if (ctx == NULL) {     return NGX_CONF_ERROR;   }   // 為配置項指針申請數(shù)組內(nèi)存   *ctx = ngx_pcalloc(cf->pool, ngx_event_max_module * sizeof(void *));   if (*ctx == NULL) {     return NGX_CONF_ERROR;   }   // 將數(shù)組值賦值到conf中,也即關(guān)聯(lián)到核心配置對象ngx_cycle_t中   *(void **) conf = ctx;   for (i = 0; cf->cycle->modules[i]; i++) {     if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) {       continue;     }     m = cf->cycle->modules[i]->ctx;     // 如果當(dāng)前模塊的create_conf()方法不為空,則調(diào)用該方法創(chuàng)建存儲配置項的結(jié)構(gòu)體     if (m->create_conf) {       (*ctx)[cf->cycle->modules[i]->ctx_index] = m->create_conf(cf->cycle);       if ((*ctx)[cf->cycle->modules[i]->ctx_index] == NULL) {         return NGX_CONF_ERROR;       }     }   }   // 這里將*cf結(jié)構(gòu)體進(jìn)行了復(fù)制,臨時存儲在pcf中,然后初始化當(dāng)前的*cf結(jié)構(gòu)體的模塊相關(guān)的參數(shù),   // 以進(jìn)行下一步的解析   pcf = *cf;   cf->ctx = ctx;   cf->module_type = NGX_EVENT_MODULE;   cf->cmd_type = NGX_EVENT_CONF;   // 解析events{}配置塊中的子配置項   rv = ngx_conf_parse(cf, NULL);   // 重新將pcf復(fù)制給*cf,以供后面返回使用   *cf = pcf;   if (rv != NGX_CONF_OK) {     return rv;   }   // 到這里,說明events{}配置塊的配置項都解析完成了,因而這里調(diào)用各個模塊的init_conf()方法,   // 進(jìn)行配置項的初始化和合并工作   for (i = 0; cf->cycle->modules[i]; i++) {     if (cf->cycle->modules[i]->type != NGX_EVENT_MODULE) {       continue;     }     m = cf->cycle->modules[i]->ctx;     // 如果當(dāng)前模塊的init_conf()不為空,則調(diào)用其init_conf()方法初始化配置項     if (m->init_conf) {       rv = m->init_conf(cf->cycle, (*ctx)[cf->cycle->modules[i]->ctx_index]);       if (rv != NGX_CONF_OK) {         return rv;       }     }   }   return NGX_CONF_OK; }

      ngx_events_block()方法主要完成的工作有如下幾個:

      ● 調(diào)用ngx_count_modules()方法對事件模塊序號進(jìn)行標(biāo)記,需要注意的是,這里的排序是針對當(dāng)前模塊在所有事件類型模塊中的順序進(jìn)行標(biāo)記,并且將序號保存在各模塊的ctx_index屬性中,比如這里的事件類型核心模塊ngx_event_core_modulectx_index就為0;

      ● 為指針ctx申請內(nèi)存空間,并且申請一個數(shù)組,將其地址賦值給ctx指針,這里的數(shù)組長度就為事件模塊的數(shù)目。其實這里的數(shù)組就是用來保存每個事件模塊的配置對象的,當(dāng)前事件模塊在所有事件模塊中的相對位置就對應(yīng)于該數(shù)組中的相對位置,這里的相對位置也即前一步中計算得到的ctx_index

      ● 調(diào)用各個事件模塊的create_conf()方法創(chuàng)建各自的配置結(jié)構(gòu)體,并且將其保存在ctx指針指向的數(shù)組中;

      ● 調(diào)用ngx_conf_parse()方法對配置文件繼續(xù)解析,前面我們已經(jīng)講到,ngx_events_block()方法就是解析到events配置項的時候才調(diào)用的,因而這里的ngx_conf_parse()方法的調(diào)用就是繼續(xù)解析events配置塊的子配置項,而該方法調(diào)用完成則說明events配置塊里的配置項都已經(jīng)解析完成;

      ● 調(diào)用各個模塊的init_conf()方法對配置項進(jìn)行初始化,簡單的說,就是,由于在nginx.conf中只配置了部分配置項的值,而剩余的配置項就由init_conf()方法來設(shè)置默認(rèn)值;

      2. ngx_event_init_conf()—-檢查事件模塊配置結(jié)構(gòu)體是否正常創(chuàng)建

      在nginx解析完nginx.conf配置文件的所有配置項后(包括前一步中講解的對events配置項的解析),其就會調(diào)用所有核心模塊的init_conf()方法對核心模塊的配置項進(jìn)行初始化。這里的核心模塊就包括ngx_events_module,該模塊的init_conf()方法指向的就是這里的ngx_event_init_conf()方法,該方法本質(zhì)上并沒有做什么工作,只是檢查了是否創(chuàng)建了存儲事件模塊配置項的結(jié)構(gòu)體數(shù)組。

      如下是ngx_event_init_conf()方法的源碼:

      static char *ngx_event_init_conf(ngx_cycle_t *cycle, void *conf) {   if (ngx_get_conf(cycle->conf_ctx, ngx_events_module) == NULL) {     ngx_log_error(NGX_LOG_EMERG, cycle->log, 0,                   "no "events" section in configuration");     return NGX_CONF_ERROR;   }   return NGX_CONF_OK; }

      上面兩個方法就是ngx_events_module核心模塊的兩個主要的配置方法,可以看到,這個核心模塊的主要作用就是創(chuàng)建了一個數(shù)組,用于存儲各個事件模塊的配置結(jié)構(gòu)體的。下面我們來看一下事件核心模塊的主要方法。

      3. ngx_event_core_create_conf()—-創(chuàng)建事件核心模塊配置結(jié)構(gòu)體

      在第1點中我們講到,解析events配置塊的子配置項之前,會調(diào)用各個事件模塊的create_conf()方法來創(chuàng)建其使用的存儲配置數(shù)據(jù)的結(jié)構(gòu)體,而后調(diào)用ngx_conf_parse()方法來解析子配置項,接著調(diào)用各個事件模塊的init_conf()方法初始化各個模塊配置數(shù)據(jù)的結(jié)構(gòu)體。

      這里ngx_event_core_module_ctx就是一個事件類型的模塊,其create_conf屬性指向的就是ngx_event_core_create_conf()方法,而init_conf屬性指向的就是ngx_event_core_init_conf()方法。

      這一節(jié)我們首先講解ngx_event_core_create_conf()方法的實現(xiàn)原理:

      static void *ngx_event_core_create_conf(ngx_cycle_t *cycle) {   ngx_event_conf_t *ecf;   ecf = ngx_palloc(cycle->pool, sizeof(ngx_event_conf_t));   if (ecf == NULL) {     return NULL;   }   ecf->connections = NGX_CONF_UNSET_UINT;   ecf->use = NGX_CONF_UNSET_UINT;   ecf->multi_accept = NGX_CONF_UNSET;   ecf->accept_mutex = NGX_CONF_UNSET;   ecf->accept_mutex_delay = NGX_CONF_UNSET_MSEC;   ecf->name = (void *) NGX_CONF_UNSET;   return ecf; }

      可以看到,這里的ngx_event_core_create_conf()方法本質(zhì)上就是創(chuàng)建了一個ngx_event_conf_t結(jié)構(gòu)體,并且將各個屬性都設(shè)置為未設(shè)置狀態(tài)。

      4. ngx_event_core_init_conf()—-初始化配置結(jié)構(gòu)體

      前面我們講到,在解析完各個子配置項之后,nginx會調(diào)用各個事件模塊的init_conf()方法,這里的核心事件模塊就是這個ngx_event_core_init_conf()方法,如下是該方法的源碼:

      static char * ngx_event_core_init_conf(ngx_cycle_t *cycle, void *conf) {   ngx_event_conf_t *ecf = conf; #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)   int                  fd; #endif   ngx_int_t i;   ngx_module_t *module;   ngx_event_module_t *event_module;   module = NULL; #if (NGX_HAVE_EPOLL) && !(NGX_TEST_BUILD_EPOLL)   // 測試是否具有創(chuàng)建epoll句柄的權(quán)限   fd = epoll_create(100);   if (fd != -1) {     // 關(guān)閉創(chuàng)建的epoll句柄,并且將module指向epoll模塊       (void) close(fd);       module = &ngx_epoll_module;   } else if (ngx_errno != NGX_ENOSYS) {       module = &ngx_epoll_module;   } #endif   // 這里,如果沒有前面判斷的模塊類型,則默認(rèn)使用事件模塊中的第一個模塊作為事件處理模型   if (module == NULL) {     for (i = 0; cycle->modules[i]; i++) {       if (cycle->modules[i]->type != NGX_EVENT_MODULE) {         continue;       }       event_module = cycle->modules[i]->ctx;       if (ngx_strcmp(event_module->name->data, event_core_name.data) == 0) {         continue;       }       module = cycle->modules[i];       break;     }   }   // 如果此時module還是為NULL,則返回異常   if (module == NULL) {     ngx_log_error(NGX_LOG_EMERG, cycle->log, 0, "no events module found");     return NGX_CONF_ERROR;   }   // 下面的操作主要是判斷各個屬性是否為初始設(shè)置的無效值,如果是,則說明nginx.conf中沒有配置   // 關(guān)于該屬性的配置項,那么這里就會為該屬性設(shè)置默認(rèn)值   ngx_conf_init_uint_value(ecf->connections, DEFAULT_CONNECTIONS);   cycle->connection_n = ecf->connections;   ngx_conf_init_uint_value(ecf->use, module->ctx_index);   event_module = module->ctx;   ngx_conf_init_ptr_value(ecf->name, event_module->name->data);   ngx_conf_init_value(ecf->multi_accept, 0);   ngx_conf_init_value(ecf->accept_mutex, 0);   ngx_conf_init_msec_value(ecf->accept_mutex_delay, 500);   return NGX_CONF_OK; }

      ngx_event_core_init_conf()方法的主要做了兩件事:

      ● 選擇當(dāng)前所使用的模塊,如果沒指定,則默認(rèn)使用第一個事件模塊;

      ● 初始化事件核心模塊的配置結(jié)構(gòu)體的各個屬性值為默認(rèn)值。

      5. ngx_event_module_init()—-核心模塊的配置項初始化

      對于ngx_event_core_module模塊而言,其還指定了兩個方法,一個是用于初始化模塊的ngx_event_module_init()方法,另一個是用于worker進(jìn)程執(zhí)行主循環(huán)邏輯之前進(jìn)行調(diào)用的ngx_event_process_init()方法。

      ngx_event_module_init()方法是在master進(jìn)程中調(diào)用的,其會在解析完nginx.conf文件中的所有配置項之后調(diào)用,本質(zhì)上,該方法的作用就是對當(dāng)前配置的核心模塊(事件模塊)進(jìn)行初始化。

      如下是ngx_event_module_init()方法的源碼:

      /**  * 當(dāng)前方法的主要作用是申請一塊用于存儲統(tǒng)計數(shù)據(jù)的共享內(nèi)存,然后設(shè)置ngx_accept_mutex_ptr、  * ngx_connection_counter、ngx_temp_number等變量的地址,如果開啟了slab stat,  * 那么還會設(shè)置ngx_stat_accepted、ngx_stat_handled、ngx_stat_requests等的地址,以統(tǒng)計

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號