Analysis of Nginx line Cheng code

Source: Internet
Author: User

  Weekend saw the Nginx thread pool part of the code, copied it again, written in its own version. Some areas of implementation are still different, but the basic structure is all excerpt.

Share it here. If you understand my version, it will prove that you understand the nginx thread pool.

This article only lists the key data structures and APIs, and focuses on understanding the nginx thread pool design ideas. The complete code is in the final link.

1. Task node

void (*cb_fun) (void *); // Task Structure Body struct task{    void        // task function parameters (to ensure that the parameter address is valid before the task execution ends)    cb_fun          Task function (the return value must be a value of 0   not 0 for increasing threads, and destroying the thread pool)    struct// task chain Pointer } zoey_task_t;

Handler is a function pointer, is the actual task function, argv is the parameter of the function, next points to the next task.

2. Task Queue

struct task_queue{    *head;  // Queue Header    zoey_task_t **tail;    // End    of queue int // Maximum task limit    int // Current number of tasks } zoey_task_queue_t;

  Head is the task queue header pointer, tail is the task queue tail pointer, Maxtasknum is the maximum queue task limit, Curtasknum is the queue current task count.

3. Thread pool

struct threadpool{    pthread_mutex_t    mutex;   // Mutual exclusion Lock    pthread_cond_t     cond;    // Conditional Lock    zoey_task_queue_t       tasks;   task queue     int       // number of threads    int       // thread stack size }zoey_threadpool_t;

The mutex is the mutex cond for the conditional lock. Mutexes and cond together ensure that the thread pool task is mutually exclusive to pick up or add.

Tasks points to the task queue.

Threadnum number of threads for the thread pool

Thread_stack_size for thread stack size

  4. Start the configuration

// Configuration Parameters struct threadpool_conf{    int threadnum;    // Number of threads    int thread_stack_size; // thread stack size    int maxtasknum; // Maximum task limit } zoey_threadpool_conf_t;

 Starting the configuration structure body is some of the parameters when the thread pool is initialized.

  

 5. Initializing the thread pool

First check that the arguments are valid, and then initialize Mutex,cond,key (pthread_key_t). Key is used to read and write thread global variables, and this global variable controls whether the thread exits.

Finally, the thread is created.

zoey_threadpool_t* Zoey_threadpool_init (zoey_threadpool_conf_t *conf) {zoey_threadpool_t*pool =NULL; intError_flag_mutex =0; intError_flag_cond =0;    pthread_attr_t attr;  Do{        if(Z_conf_check (conf) = =-1){//Check if the parameters are legitimate             Break; } Pool= (zoey_threadpool_t *)malloc(sizeof(zoey_threadpool_t));//apply thread pool handle        if(Pool = =NULL) {             Break; }        //initialize thread pool basic parametersPool->threadnum = conf->Threadnum; Pool->thread_stack_size = conf->thread_stack_size; Pool->tasks.maxtasknum = conf->Maxtasknum; Pool->tasks.curtasknum =0; Z_task_queue_init (&pool->tasks); if(Z_thread_key_create ()! =0){//Create a pthread_key_t to access the thread global variables.              Free(pool);  Break; }        if(Z_thread_mutex_create (&pool->mutex)! =0){//Initialize Mutex lockZ_thread_key_destroy ();  Free(pool);  Break; }        if(Z_thread_cond_create (&pool->cond)! =0){//initializing a conditional lockZ_thread_key_destroy (); Z_thread_mutex_destroy (&pool->mutex);  Free(pool);  Break; }        if(Z_threadpool_create (pool)! =0){//Create a thread poolZ_thread_key_destroy (); Z_thread_mutex_destroy (&pool->mutex); Z_thread_cond_destroy (&pool->cond);  Free(pool);  Break; }        returnPool; } while(0); returnNULL;}

 

 6. Add a task

First, request a task node, instantiate it, join the node to the task queue, and notify the other processes of new tasks by adding the current task queue. Lock the whole process.

intZoey_threadpool_add_task (zoey_threadpool_t *pool, Cb_fun handler,void*argv) {zoey_task_t*task =NULL; //Request a Task node and assign a valueTask = (zoey_task_t *)malloc(sizeof(zoey_task_t)); if(Task = =NULL) {        return-1; } Task->handler =handler; Task->ARGV =argv; Task->next =NULL; if(Pthread_mutex_lock (&pool->mutex)! =0){//Locking         Free(Task); return-1; }     Do{        if(Pool->tasks.curtasknum >= Pool->tasks.maxtasknum) {//determine if the number of tasks in the work queue is up to limit             Break; }        //to end a task node in a task queue* (Pool->tasks.tail) =task; Pool->tasks.tail = &task->Next; Pool->tasks.curtasknum++; //notifies the blocked thread        if(Pthread_cond_signal (&pool->cond)! =0){             Break; }        //UnlockPthread_mutex_unlock (&pool->mutex); return 0; } while(0); Pthread_mutex_unlock (&pool->mutex);  Free(Task); return-1;}

 

 7. Destroying the thread pool

Destroying the thread pool is also adding tasks to the task queue, but adding the task is to have the thread exit. The Z_THREADPOOL_EXIT_CB function will lock 0 back out of the thread, and a lock of 0 indicates that it

Has exited and then exits the next thread. The thread frees all resources after exiting.

voidZoey_threadpool_destroy (zoey_threadpool_t *pool) {unsignedintn =0; volatileUnsignedint  Lock; //the Z_THREADPOOL_EXIT_CB function causes the corresponding thread to exit     for(N < pool->threadnum; n++){        Lock=1; if(Zoey_threadpool_add_task (Pool, Z_THREADPOOL_EXIT_CB, &Lock) !=0){            return; }         while(Lock) {Usleep (1); }} Z_thread_mutex_destroy (&pool->mutex); Z_thread_cond_destroy (&pool->cond);    Z_thread_key_destroy ();  Free(pool);}

 

 8. Add a thread

It is simple to generate a thread and the number of threads + +. Locking

int zoey_thread_add (zoey_threadpool_t *pool) {    int0;     if 0 ) {        return -1;    }     = Z_thread_add (pool);    Pthread_mutex_unlock (&pool->mutex);     return ret;}

 

9. Change task Queue maximum task limit

When Num=0 is set, the number of threads is infinitely large.

void int num) {    if0) {        return -1;    }    Z_change_maxtask_num (pool, num);   // Change the maximum task limit    Pthread_mutex_unlock (&pool->mutex);}

usage Examples

intMain () {intarray[10000] = {0}; inti =0; zoey_threadpool_conf_t conf= {5,0,5};//Instantiating startup Parameterszoey_threadpool_t *pool = Zoey_threadpool_init (&conf);//initializing the thread pool    if(Pool = =NULL) {        return 0; }     for(; I <10000; i++) {Array[i]=i; if(i = = the) {zoey_thread_add (pool);//Increase Threadzoey_thread_add (pool); }                if(i = = -) {zoey_set_max_tasknum (pool,0);//Change Maximum task number 0 to do not limit        }         while(1){            if(Zoey_threadpool_add_task (pool, Testfun, &array[i]) = =0){                 Break; } printf ("error in i =%d\n", i);    }} Zoey_threadpool_destroy (pool);  while(1) {Sleep (5); }    return 0;}

One. Source Code

HTTPS://github.com/unlikewashface/zoey_threadpool.git

Analysis of Nginx line Cheng code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.