This section is concerned with the implementation of the Nginx central thread pool module;
General description
(1) thread pool module belongs to the core module, so its configuration memory ngx_thread_pool_conf_t will be pre-applied, and the main management of each thread pool structure in ngx_thread_pool_conf_t;
(2) Each thread pool is created and each thread pool is destroyed in Ngx_thread_pool_init_worker and Ngx_thread_pool_exit_worker respectively;
Thread Pool Module
ngx_module_t ngx_thread_pool_module = { ngx_module_v1, &ngx_thread_pool_module_ctx,/ * module Context * /ngx_thread_pool_commands, /* Module directives * /Ngx_core_module, /* Module type * // /Core Module NULL,/ * init Master */ NULL,/ * init module */ Ngx_thread_pool_init_worker,/ * Init process */ NULL,/ * init thread */ NULL,/ * exit thread */ ngx_thread_pool_exit_worker,< c20/>/* Exit Process */ NULL,/ * Exit Master */ ngx_module_v1_padding};
Core Module Context
Core module Context static ngx_core_module_t Ngx_thread_pool_module_ctx = { ngx_string ("Thread_pool"), ngx_ thread_pool_create_conf, ngx_thread_pool_init_conf};
Thread module Configuration structure
Thread module Configuration structure typedef struct { ngx_array_t pools; Manage multiple thread pools} ngx_thread_pool_conf_t;
Request Configuration Memory
Thread module configuration request memory static void *ngx_thread_pool_create_conf (ngx_cycle_t *cycle) { ngx_thread_pool_conf_t *tcf; TCF = Ngx_pcalloc (cycle->pool, sizeof (ngx_thread_pool_conf_t)); if (TCF = = null) { return null; } The total number of thread pools if (Ngx_array_init (&tcf->pools, Cycle->pool, 4, sizeof (ngx_thread_pool_t *)) ! = Ngx_ok) { return NULL; } return TCF;}
Default initialization configuration
//thread module configuration initialize static char *ngx_thread_pool_init_conf (ngx_cycle_t *cycle, void *conf) {ngx_ thread_pool_conf_t *tcf = conf; ngx_uint_t i; ngx_thread_pool_t **TPP; TPP = tcf->pools.elts; for (i = 0; i < tcf->pools.nelts; i++) {if (tpp[i]->threads) {//The number of threads is not 0 o'clock, skip continue directly; } if (Tpp[i]->name.len = = Ngx_thread_pool_default.len && ngx_strncmp (tpp[i]->name.data , Ngx_thread_pool_default.data, ngx_thread_pool_default.len) = = 0) { Tpp[i]->threads = 32; Default number of threads Tpp[i]->max_queue = 65536; The default number of tasks continue; } ngx_log_error (Ngx_log_emerg, Cycle->log, 0, "Unknown thread pool \"%v\ "in%s:%ui", &tpp[i]->name, Tpp[i]->file, tpp[i]->line); return ngx_conf_error; } return NGX_CONF_OK;}
Thread pool Module Configuration item description
Static ngx_command_t ngx_thread_pool_commands[] = { {ngx_string ("Thread_pool"), ngx_main_conf| Ngx_direct_conf| Ngx_conf_take23, //main configuration item Ngx_thread_pool, //Parse function 0, 0, NULL}, Ngx_null_command} ;
"Ngx_thread_pool" Configuration resolution
"ngx_thread_pool" configuration resolves 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; TP = Ngx_thread_pool_add (cf, &value[1]); Add the thread pool if (tp = = NULL) {return ngx_conf_error; } if (tp->threads) {ngx_conf_log_error (Ngx_log_emerg, CF, 0, "duplicate thread poo L \ "%v\" ", &tp->name); return ngx_conf_error; } tp->max_queue = 65536; for (i = 2; i < cf->args->nelts; i++) {if (ngx_strncmp (Value[i].data, "threads=", 8) = = 0) {T P->threads = Ngx_atoi (Value[i].data + 8, value[i].len-8);//number of threads set if (Tp->threads = = (ngx_uint_t) ngx_e Rror | | Tp->threads = = 0) {ngx_conf_log_error (Ngx_log_emerg, CF, 0, "invalid Threads value \ "%v\" ", &value[i]); return ngx_conf_error; } continue; } if (ngx_strncmp (Value[i].data, "max_queue=", ten) = = 0) {tp->max_queue = Ngx_atoi (value[i].data + 1 0, value[i].len-10);//Task number set if (Tp->max_queue = = Ngx_error) {ngx_conf_log_error (ngx_log_em ERG, CF, 0, "Invalid Max_queue value \"%v\ "", &value[i]); return ngx_conf_error; } continue; }} if (tp->threads = = 0) {//If the thread pool is empty ngx_conf_log_error (Ngx_log_emerg, CF, 0, "\"%v\ "must have \" threads\ "parameter", &cmd->name); return ngx_conf_error; } return NGX_CONF_OK;}
Called before the worker process enters the main loop
Call the static Ngx_int_tngx_thread_pool_init_worker (ngx_cycle_t *cycle) {ngx_uint_t i) before the worker process enters the loop ; ngx_thread_pool_t **TPP; ngx_thread_pool_conf_t *tcf; if (ngx_process! = Ngx_process_worker && ngx_process! = ngx_process_single) { return ngx_ok; } TCF = (ngx_thread_pool_conf_t *) ngx_get_conf (cycle->conf_ctx, ngx_thread_pool_module); if (TCF = = NULL) { return ngx_ok; } Initialize completed task queue header Ngx_thread_pool_queue_init (&ngx_thread_pool_done); TPP = tcf->pools.elts; for (i = 0; i < tcf->pools.nelts; i++) { if (Ngx_thread_pool_init (Tpp[i], Cycle->log, cycle->pool)! = Ngx _OK) { //Initialize each thread pool return ngx_error; } } return NGX_OK;}
Called before the worker process exits
Call the static Voidngx_thread_pool_exit_worker (ngx_cycle_t *cycle) {ngx_uint_t i) before the worker process exits ; ngx_thread_pool_t **TPP; ngx_thread_pool_conf_t *tcf; if (ngx_process! = Ngx_process_worker && ngx_process! = ngx_process_single) { return; } TCF = (ngx_thread_pool_conf_t *) ngx_get_conf (cycle->conf_ctx, ngx_thread_pool_module); if (TCF = = NULL) { return; } TPP = tcf->pools.elts; for (i = 0; i < tcf->pools.nelts; i++) { Ngx_thread_pool_destroy (tpp[i]); Destroy each thread pool }}
Thread pool Description
Thread pool description struct ngx_thread_pool_s { ngx_thread_mutex_t mtx;//Mutex ngx_thread_pool_queue_t queue;// Task Queue ngx_int_t waiting; Number of tasks waiting ngx_thread_cond_t cond;//condition ngx_log_t *log; ngx_str_t name; Thread pool name ngx_uint_t threads; Number of thread pools ngx_int_t The maximum number of max_queue;//tasks U_char *file; ngx_uint_t line ;};
Initialize a thread pool
Initializes a thread pool of static ngx_int_tngx_thread_pool_init (ngx_thread_pool_t *tp, ngx_log_t *log, ngx_pool_t *pool) {int Err pthread_t Tid; ngx_uint_t N; pthread_attr_t attr; if (ngx_notify = = NULL) {//No notification processing ngx_log_error (ngx_log_alert, log, 0, "The configured event Metho D cannot is used with thread pools "); return ngx_error; } ngx_thread_pool_queue_init (&tp->queue); Initialize the thread pool in the task queue if (ngx_thread_mutex_create (&TP->MTX, log)! = NGX_OK) {//Create the pool of mutex return ngx_error; } if (Ngx_thread_cond_create (&tp->cond, log)! = NGX_OK) {//Create the thread pool's condition variable (void) Ngx_thread_mutex_destro Y (&tp->mtx, log); return ngx_error; } tp->log = log; Err = Pthread_attr_init (&attr); Set thread Properties if (Err) {ngx_log_error (Ngx_log_alert, log, err, "Pthread_attr_init () failed"); return ngx_error; } #if 0 err = pthread_attr_setstacksize (&amP;attr, pthread_stack_min); Set stack size if (err) {ngx_log_error (Ngx_log_alert, log, err, "pthread_attr_setstacksize () fail Ed "); return ngx_error; } #endif for (n = 0; n < tp->threads; n++) {err = Pthread_create (&tid, &attr, NGX_THREAD_POOL_CYCL E, TP);//create thread pool, ngx_thread_pool_cycle function if (err) {ngx_log_error (Ngx_log_alert, log, err, "Pthread_create () failed"); return ngx_error; }} (void) Pthread_attr_destroy (&attr); Destroy thread property return NGX_OK;}
Destroying the thread pool
Destroys the thread pool static Voidngx_thread_pool_destroy (ngx_thread_pool_t *tp) { ngx_uint_t n; ngx_thread_task_t task; volatile ngx_uint_t lock; Ngx_memzero (&task, sizeof (ngx_thread_task_t)); Task.handler = ngx_thread_pool_exit_handler;//Task exits execution function task.ctx = (void *) &lock;//points to incoming parameter for (n = 0; n < tp->threads; n++) {All the thread pools in//TP add the task lock = 1; if (Ngx_thread_task_post (TP, &task)! = NGX_OK) { return; } while (lock) {//Master process determines if lock does not change, let the CPU execute to other threads, waiting, equivalent to Pthread_join Ngx_sched_yield (); } task.event.active = 0; } At this point, all the threads have exited (void) Ngx_thread_cond_destroy (&tp->cond, tp->log);//Conditional variable destruction (void) ngx_ Thread_mutex_destroy (&TP->MTX, tp->log);//Mutex destroy}//each thread's exit task static Voidngx_thread_pool_exit_handler ( void *data, ngx_log_t *log) { ngx_uint_t *lock = data;//Gets the parameter *lock = 0;//becomes 0 pthread_exit (0);}
"Nginx Core module" thread pool module