Thread Pool Code

Source: Internet
Author: User

Header file Head.h

#ifndef __threadpool_h_#define __threadpool_h_typedef struct threadpool_t threadpool_t;/** * @function Threadpool_ Create * @descCreates a threadpool_t object. * @param thr_num Thread num * @param max_thr_num max thread size * @param queue_max_size size of the queue. * @return A newly created thread pool or NULL */threadpool_t *threadpool_create (int min_thr_num, int max_thr_num, int queu e_max_size)/** * @function Threadpool_add * @desc Add a new task in the queue of a thread pool * @param pool thread P Ool to which add the task. * @param function Pointer to the function, that would perform the task. * @param argument argument to being passed to the function. * @return 0 if all goes well,else-1 */int threadpool_add (threadpool_t *pool, void* (*function) (void *arg), void *arg);/** * @function Threadpool_destroy * @desc Stops and destroys a thread pool. * @param pool Thread pool to destroy. * @return 0 if destory success else-1 */int Threadpool_destroy (threadpool_t *pool);/** * @desc gET the thread num * @pool Pool ThreadPool * @return # of the thread */int threadpool_all_threadnum (threadpool_t *pool);/** * desc Get the busy thread num * @param pool ThreadPool * Return # of the busy thread */int threadpool_busy_threadnum (THR eadpool_t *pool); #endif

  

Main.c

#include <stdlib.h> #include <pthread.h> #include <unistd.h> #include <assert.h> #include < stdio.h> #include <string.h> #include <signal.h> #include <errno.h> #include "threadpool.h" # Define Default_time/*10s Detection once */#define MIN_WAIT_TASK_NUM 10/* If queue_size > Min_wait_tas    K_num add a new thread to the thread pool */#define DEFAULT_THREAD_VARY 10/* Each time the number of threads created and destroyed */#define TRUE 1#define false 0typedef struct {          void * (*function) (void *);                          /* function pointer, callback function */void *arg;                    /* The parameters of the above function */} threadpool_task_t;               /* Each sub-thread task structure body *//* describes thread pool related information */struct threadpool_t {pthread_mutex_t lock;     /* For locking the structure */pthread_mutex_t thread_counter;      /* Record the number of busy threads de-busy_thr_num */pthread_cond_t queue_not_full;     /* When the task queue is full, the thread that added the task is blocked, waiting for this condition variable */pthread_cond_t queue_not_empty;                 /* When the task queue is not empty, notify the thread waiting for the task */pthread_t *threads; /* Store the TID for each thread in the thread pool. Array */Pthread_t Adjust_tid;      /* Save admin thread tid */threadpool_task_t *task_queue;                    /* Task Queue */int min_thr_num;                    /* thread pool minimum number of threads */int max_thr_num;                   /* thread pool maximum thread count */int live_thr_num;                   /* Current number of surviving threads */int busy_thr_num;              /* Number of busy threads */int wait_exit_thr_num;                    /* Number of threads to destroy */int queue_front;                     /* Task_queue Team head subscript */int queue_rear;                     /* Task_queue tail subscript */int queue_size;                 /* Number of actual tasks in Task_queue team */int queue_max_size;                       /* Task_queue queue can hold the maximum number of tasks */int shutdown;  /* flag bit, thread pool usage state, true or false */};/** * @function void *threadpool_thread (void *threadpool) * @desc the worker thread * @param ThreadPool the pool which own the thread */void *threadpool_thread (void *threadpool);/** * @function void *adjust_thread ( void *threadpool); * @desc Manager Thread * @param threadpool the ThreadPool */void *adjust_thread (void *threadpool);/** * Check a thread is Alive */int is_thread_alive (pthread_t tid); int Threadpool_free (threadpool_t *poo    l); threadpool_t *threadpool_create (int min_thr_num, int max_thr_num, int queue_max_size) {int i;    threadpool_t *pool = NULL; Do {if (pool = (threadpool_t *) malloc (sizeof (threadpool_t)) = = NULL) {printf ("malloc ThreadPool FAI            L ");        break;/* jump out do while*/} pool->min_thr_num = Min_thr_num;        Pool->max_thr_num = Max_thr_num;        Pool->busy_thr_num = 0;               Pool->live_thr_num = Min_thr_num;                           /* Number of active threads initial value = minimum number of threads */pool->queue_size = 0;        /* There are 0 products */pool->queue_max_size = queue_max_size;        Pool->queue_front = 0;        pool->queue_rear = 0;                         Pool->shutdown = false; /* Do not close the thread pool */* to open up space for the working thread array based on the maximum number of threads, and clear 0 */pool->threads = (pthread_t *) malloc (sizeof (pthread_t) *max_    Thr_num);     if (pool->threads = = NULL) {printf ("malloc threads Fail");        Break        } memset (pool->threads, 0, sizeof (pthread_t) *max_thr_num);        /* Queue Open space */Pool->task_queue = (threadpool_task_t *) malloc (sizeof (threadpool_task_t) *queue_max_size);            if (Pool->task_queue = = NULL) {printf ("malloc task_queue fail");        Break }/* Initialize mutex, condition variable */if (Pthread_mutex_init (& (Pool->lock), NULL)! = 0 | | pthread_mutex_ Init (& (Pool->thread_counter), NULL)! = 0 | | Pthread_cond_init (& (Pool->queue_not_empty), NULL)! = 0 | |            Pthread_cond_init (& (Pool->queue_not_full), NULL)! = 0) {printf ("Init the Lock or cond fail");        Break }/* Start min_thr_num work thread */for (i = 0; i < Min_thr_num; i++) {Pthread_create (& ( Pool->threads[i]), NULL, Threadpool_thread, (void *) pool);/*pool points to the current thread pool */printf ("Start Thread 0x%x...\n", (unsigned int) pool->threads[i]);    } pthread_create (& (Pool->adjust_tid), NULL, Adjust_thread, (void *) pool);/* Start the manager thread */return pool;    } while (0);      Threadpool_free (pool); /* When the preceding code call fails, free the poll storage space */return NULL;} /* Add a task to the thread pool */int threadpool_add (threadpool_t *pool, void* (*function) (void *arg), void *arg) {Pthread_mutex_lock (&A    MP; (Pool->lock));        /* = = True, queue is full, wait is blocked */while ((pool->queue_size = = pool->queue_max_size) && (!pool->shutdown)) {    Pthread_cond_wait (& (Pool->queue_not_full), & (Pool->lock));    } if (Pool->shutdown) {Pthread_mutex_unlock (& (Pool->lock)); }/* Clears the parameters of the callback function called by the worker thread Arg */if (pool->task_queue[pool->queue_rear].arg! = NULL) {Free (pool->task        _QUEUE[POOL-&GT;QUEUE_REAR].ARG);    Pool->task_queue[pool->queue_rear].arg = NULL; }/* Add task to Task queue */pool->tAsk_queue[pool->queue_rear].function = function;    Pool->task_queue[pool->queue_rear].arg = arg;       Pool->queue_rear = (pool->queue_rear + 1)% pool->queue_max_size;    /* tail pointer movement, analog ring */pool->queue_size++;    /* After the task is added, the queue is not empty, and the thread that waits for processing tasks in the thread pool is awakened */pthread_cond_signal (& (Pool->queue_not_empty));    Pthread_mutex_unlock (& (Pool->lock)); return 0;}    /* Each worker thread in the thread pool */void *threadpool_thread (void *threadpool) {threadpool_t *pool = (threadpool_t *) ThreadPool;    threadpool_task_t task; while (true) {/* Lock must be taken-to-wait on conditional variable/* * Just create the thread, wait for tasks in the task queue, or block wait for tasks in the task queue before        Wake-Up Reception task */Pthread_mutex_lock (& (Pool->lock)); /*queue_size = = 0 indicates no task, the wait is blocked on the condition variable, if there is a task, skip the while*/while ((pool->queue_size = = 0) && (!pool->s            Hutdown) {printf ("Thread 0x%x is waiting\n", (unsigned int) pthread_self ()); Pthread_cond_wait (& (Pool->queue_not_empty), & (POol->lock)); /* Clears the specified number of idle threads, if the number of threads to end is greater than 0, end thread */if (Pool->wait_exit_thr_num > 0) {pool->wait_exit_t                hr_num--; /* If the number of thread constructor threads is greater than the minimum value, you can end the current thread */if (Pool->live_thr_num > Pool->min_thr_num) {prin                    TF ("Thread 0x%x is exiting\n", (unsigned int) pthread_self ());                    pool->live_thr_num--;                    Pthread_mutex_unlock (& (Pool->lock));                Pthread_exit (NULL); }}}//If you specify true, to close each thread of the line constructor, self-exits processing */if (Pool->shutdown) {pthread_mutex_            Unlock (& (Pool->lock));            printf ("Thread 0x%x is exiting\n", (unsigned int) pthread_self ());     Pthread_exit (NULL); /* thread ends itself */}/* Get task from Task queue, is an out of team operation */task.function = Pool->task_queue[pool->queue_front].func        tion;        Task.arg = pool->task_queue[pool->queue_front].arg; Pool->queue_front = (pool->queue_front + 1)% pool->queue_max_size;        /* Out of the team, simulate the ring queue */pool->queue_size--;        /* Notifications can have new tasks added in */Pthread_cond_broadcast (& (Pool->queue_not_full));        /* The thread pool is released immediately after the task is removed/Pthread_mutex_unlock (& (Pool->lock));        /* Perform task */printf ("Thread 0x%x start working\n", (unsigned int) pthread_self ());                            Pthread_mutex_lock (& (Pool->thread_counter));                                                   /* Busy number of threads variable */pool->busy_thr_num++;        /* Number of busy threads +1*/Pthread_mutex_unlock (& (Pool->thread_counter)); (* (task.function))                                           (Task.arg);                                              /* Perform callback function task *///task.function (TASK.ARG);        /* Perform a callback function task//////* Task End processing */printf ("Thread 0x%x End working\n", (unsigned int) pthread_self ());        Pthread_mutex_lock (& (Pool->thread_counter));    pool->busy_thr_num--;                                   /* Dispose of a task, number of busy states Threads -1*/Pthread_mutex_unlock (& (Pool->thread_counter)); } pthread_exit (NULL);}    /* Manage thread */void *adjust_thread (void *threadpool) {int i;    threadpool_t *pool = (threadpool_t *) ThreadPool;                                    while (!pool->shutdown) {sleep (default_time);        /* Timed to thread pool management */Pthread_mutex_lock (& (Pool->lock));                      int queue_size = pool->queue_size;                  /* Focus on tasks */int live_thr_num = pool->live_thr_num;        /* Number of surviving threads */Pthread_mutex_unlock (& (Pool->lock));        Pthread_mutex_lock (& (Pool->thread_counter));                  int busy_thr_num = pool->busy_thr_num;        /* Number of busy threads */Pthread_mutex_unlock (& (Pool->thread_counter)); /* Create a new threading algorithm: The number of tasks is greater than the minimum number of thread pools, and the number of threads surviving is less than the maximum thread count: 30>=10 && 40<100*/if (queue_size >= min_wait_task_n UM && Live_thr_num < Pool->max_thr_num) {Pthread_mutex_lock (& (Pool->lock));            int add = 0;                    /* Add Default_thread threads at a time */for (i = 0; i < pool->max_thr_num && Add < Default_thread_vary && Pool->live_thr_num < pool->max_thr_num; i++) {if (pool->threads[i] = = 0 | |!is_thread_alive (pool->threads[i])) {Pthread_                    Create (& (Pool->threads[i]), NULL, Threadpool_thread, (void *) pool);                    add++;                pool->live_thr_num++;        }} pthread_mutex_unlock (& (Pool->lock));  }/* Destroys redundant idle threading algorithm: The busy thread X2 is less than the number of surviving threads and the number of surviving threads is greater than the minimum number of threads */if ((Busy_thr_num * 2) < Live_thr_num && Live_thr_num > Pool->min_thr_num) {/* Destroy Default_thread threads one at a time, at random 10 */Pthread_mutex_lock (&            amp; (pool->lock));      Pool->wait_exit_thr_num = default_thread_vary; /* Number of threads to destroy setis ten */Pthread_mutex_unlock (& (Pool->lock)); for (i = 0; i < default_thread_vary; i++) {/* Notifies threads that are idle, they will terminate by themselves */pthread_cond_signal            (& (Pool->queue_not_empty)); }}} return NULL;}    int Threadpool_destroy (threadpool_t *pool) {int i;    if (pool = = NULL) {return-1;    } Pool->shutdown = true;    /* First destroy the management thread */Pthread_join (Pool->adjust_tid, NULL); for (i = 0; i < pool->live_thr_num; i++) {/* Notifies all idle threads */Pthread_cond_broadcast (& (Pool->queue_n    Ot_empty));    } for (i = 0; i < pool->live_thr_num; i++) {pthread_join (pool->threads[i], NULL);    } threadpool_free (pool); return 0;}    int Threadpool_free (threadpool_t *pool) {if (pool = = NULL) {return-1;    } if (Pool->task_queue) {free (pool->task_queue);        } if (pool->threads) {free (pool->threads); Pthread_mutex_lock (& (POOL-&GT;lock));        Pthread_mutex_destroy (& (Pool->lock));        Pthread_mutex_lock (& (Pool->thread_counter));        Pthread_mutex_destroy (& (Pool->thread_counter));        Pthread_cond_destroy (& (Pool->queue_not_empty));    Pthread_cond_destroy (& (Pool->queue_not_full));    } free (pool);    Pool = NULL; return 0;}    int Threadpool_all_threadnum (threadpool_t *pool) {int all_threadnum =-1;    Pthread_mutex_lock (& (Pool->lock));    All_threadnum = pool->live_thr_num;    Pthread_mutex_unlock (& (Pool->lock)); return all_threadnum;}    int Threadpool_busy_threadnum (threadpool_t *pool) {int busy_threadnum =-1;    Pthread_mutex_lock (& (Pool->thread_counter));    Busy_threadnum = pool->busy_thr_num;    Pthread_mutex_unlock (& (Pool->thread_counter)); return busy_threadnum;}     int is_thread_alive (pthread_t tid) {int kill_rc = Pthread_kill (tid, 0);    Send signal number NO. 0 to test if the thread survives if (KILL_RC = = Esrch) {return false; }   return true;} /* Test */#if thread in 1/* thread pool, simulate processing business */void *process (void *arg) {printf ("Thread 0x%x working on Task%d\n", (unsigned int) pthr    Ead_self (), * (int *) arg);    Sleep (1);    printf ("Task%d is end\n", * (int *) arg); return NULL;} int main (void) {/*threadpool_t *threadpool_create (int min_thr_num, int max_thr_num, int queue_max_size); */Threadpoo    l_t *THP = threadpool_create (3,100,100);/* Create thread pool, minimum 3 threads in pool, max 100, queue max 100*/printf ("Pool inited");    int *num = (int *) malloc (sizeof (int) *20);    int num[20], I;        for (i = 0; i <; i++) {num[i]=i;        printf ("Add Task%d\n", i);     Threadpool_add (THP, process, (void*) &num[i]);                                          /* Add a task to the thread pool */} sleep (10);    /* Wait for child threads to complete tasks */Threadpool_destroy (THP); return 0;}

  

Thread Pool 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.