nginx源碼分析線程池詳解
一、前言
nginx是采用多進程模型,master和worker之間主要通過pipe管道的方式進行通信,多進程的優勢就在于各個進程互不影響。但是經常會有人問道,nginx為什么不采用多線程模型(這個除了之前一篇文章講到的情況,別的只有去問作者了,HAHA)。其實,nginx代碼中提供了一個thread_pool(線程池)的核心模塊來處理多任務的。下面就本人對該thread_pool這個模塊的理解來跟大家做些分享(文中錯誤、不足還請大家指出,謝謝)
二、thread_pool線程池模塊介紹
nginx的主要功能都是由一個個模塊構成的,thread_pool也不例外。線程池主要用于讀取、發送文件等IO操作,避免慢速IO影響worker的正常運行。先引用一段官方的配置示例
Syntax: thread_pool name threads=number [max_queue=number];Default: thread_pool default threads=32 max_queue=65536;Context: main
根據上述的配置說明,thread_pool是有名字的,上面的線程數目以及隊列大小都是指每個worker進程中的線程,而不是所有worker中線程的總數。一個線程池中所有的線程共享一個隊列,隊列中的最大人數數量為上面定義的max_queue,如果隊列滿了的話,再往隊列中添加任務就會報錯。
根據之前講到過的模塊初始化流程(在master啟動worker之前) create_conf--> command_set函數-->init_conf,下面就按照這個流程看看thread_pool模塊的初始化
/******************* nginx/src/core/ngx_thread_pool.c ************************///創建線程池所需的基礎結構static void * ngx_thread_pool_create_conf(ngx_cycle_t *cycle){ ngx_thread_pool_conf_t *tcf; //從cycle->pool指向的內存池中申請一塊內存 tcf = ngx_pcalloc(cycle->pool, sizeof(ngx_thread_pool_conf_t)); if (tcf == NULL) { return NULL; } //先申請包含4個ngx_thread_pool_t指針類型元素的數組 //ngx_thread_pool_t結構體中保存了一個線程池相關的信息 if (ngx_array_init(&tcf->pools, cycle->pool, 4, sizeof(ngx_thread_pool_t *)) != NGX_OK) { return NULL; } return tcf;} //解析處理配置文件中thread_pool的配置,并將相關信息保存的ngx_thread_pool_t中static char * ngx_thread_pool(ngx_conf_t *cf, ngx_command_t *cmd, void *conf){ ngx_str_t *value; ngx_uint_t i; ngx_thread_pool_t *tp; value = cf->args->elts; //根據thread_pool配置中的name作為線程池的唯一標識(如果重名,只有第一個有效) //申請ngx_thread_pool_t結構保存線程池的相關信息 //由此可見,nginx支持配置多個name不同的線程池 tp = ngx_thread_pool_add(cf, &value[1]); ....... //處理thread_pool配置行的所有元素 for (i = 2; i < cf->args->nelts; i++) { //檢查配置的線程數 if (ngx_strncmp(value[i].data, "threads=", 8) == 0) { ....... } //檢查配置的最大隊列長度 if (ngx_strncmp(value[i].data, "max_queue=", 10) == 0) { ....... } } ......} //判斷包含多個線程池的數組中的各個線程池的配置是否正確static char * ngx_thread_pool_init_conf(ngx_cycle_t *cycle, void *conf){ .... ngx_thread_pool_t **tpp; tpp = tcf->pools.elts; //遍歷數組中所有的線程池配置,并檢查其正確性 for (i = 0; i < tcf->pools.nelts; i++) { ..... } return NGX_CONF_OK;}
新聞熱點
疑難解答