Thread Pool Learning Notes

Source: Internet
Author: User
Tags assert

Record the process of learning the thread pool, the function that the code uses boils down To:
Pthread_mutex_lock
Pthread_mutex_unlock
Pthread_cond_wait
Pthread_cond_signal
Pthread_cond_broadcast
Pthread_create
Pthread_join
The program also uses a linked list,
There is also a knowledge point: any type of data can be of type void,
however, the type of void must be cast before it is Used.

/**author:greens_ren*description: thread Pool *//* header File */#include <pthread.h>#include <stdio.h>/* Begin:add */#include <stdlib.h>#include <unistd.h>#include <assert.h>#include <sys/types.h>/* End:add *//* Data Structure */typedefstruct thread_worker{void * (*worker) (void *arg);void * arg;struct Thread_worker *next;} cthread_worker;typedefstruct thread_pool{pthread_mutex_t queue_lock; pthread_cond_t queue_ready;int max_thread_num; pthread_t *phead_threadid;int cur_queue_size; Cthread_worker *phead;int shutdown;} cthread_pool;/* Global Zone */static Cthread_pool *pool =NULL;/* function */void Pthread_init (int max_thread_num);void *thread_roution (void * arg);void Pthread_add_worker (void * (*worker) (void *arg),void * arg);void Pthread_destroy (void);void* my_process (void *arg);/*main*/int main (Void) {int max_thread_num =3;int worker_num =10;/* Initialize */pthread_init (max_thread_num);/* put into task */int *workernum = (int *) malloc (sizeofInt) * worker_num);int i;For (i =0; I < worker_num; I++) {workernum[i] = i; pthread_add_worker (my_process, &workernum[i]);}/* wait for processing task */sleep (8); Pthread_destroy ();Return0;}void Pthread_init (int Max_thread_num) {pool = (cthread_pool*) malloc (sizeof (cthread_pool));/*free (pool) *//* Begin:modified Initialize the mutex and condition variable */pthread_mutex_init (& (pool->queue_lock),NULL); Pthread_cond_init (& (pool->queue_ready),NULL);/* end:modified *//* Initialize Thread */pool->max_thread_num = max_thread_num; Pool->phead_threadid = (pthread_t *) malloc (sizeof (pthread_t) * max_thread_num);/*free*/int i;For (i =0; I < max_thread_num; i + +) {pthread_create (& (pool->phead_threadid[i]),NULL, thread_roution,NULL); }/* Initialize task wait queue */pool->cur_queue_size =0;Pool->phead = (cthread_worker *) malloc (sizeof (cthread_worker));Pool->phead->next = NULL;/* sin, There's more to consider Here. A pointer is stored in the pool, except that it specifies a list of links */pool->phead =NULL;/* thread pool Destroy flag */pool->shutdown =0;return;}void *thread_roution (void * Arg) {printf ("starting thread 0x%x\n", pthread_self ());While1)/*added threads to run continuously, consider using while (1) to implement */{pthread_mutex_lock (& (pool->queue_lock));/* if no task is currently being processed and the thread pool is not destroyed, wait for the task to be added */If (pool->cur_queue_size = = 0 && pool->shutdown! = 1)While (pool->cur_queue_size = =0 && pool->shutdown! =1)/*modified by*/{Pthread_cond_wait (& (pool->queue_lock), & (pool->queue_ready)); printf"thread 0x%x is waiting\n", pthread_self ()); Pthread_cond_wait (& (pool->queue_ready), & (pool->queue_lock)); }/* If the thread pool has been flagged for destruction, exit the threads */if (pool->shutdown = =1) {pthread_mutex_unlock (& (pool->queue_lock)); printf ("thread 0x%x would exit\n", pthread_self ()); Pthread_exit (NULL); } printf ("thread 0x%x is starting to work\n", pthread_self ());/*assert is a good assistant for debugging, and if it is home, it will print the error message via STDERR and terminate the program */assert (pool->cur_queue_size! =0); Assert (pool->shutdown! =1);/* Start processing tasks in the wait queue *//* callback function */pool->cur_queue_size--; Cthread_worker * worker_waiting = pool->phead; Pool->phead = worker_waiting->next;/* The purpose of this lock is to deal with the task chain list, after processing can be unlocked, so that other threads to process the task linked list */pthread_mutex_unlock (& (pool->queue_lock));/*modified by the beginning of the explanation lock placed behind the callback function, here to do the correction *//* call the callback function to perform the task */(* (worker_waiting->worker)) (worker_waiting->arg);/* Delete the task node already executed in the list */free (worker_waiting); Worker_waiting =NULL; }}void Pthread_add_worker (void * (*worker) (void *arg),void * Arg) {assert (worker! =NULL); Assert (pool->shutdown! =1);/* build a new task insert to the end of the task List */cthread_worker * Worker_insert = (cthread_worker *) malloc (sizeof (cthread_worker));/*free*/worker_insert->worker = worker; Worker_insert->arg = arg; Worker_insert->next =NULL;/* below to process the task chain list, here to lock, protect the linked List. The first time I wrote, I forgot locking. */pthread_mutex_lock (& (pool->queue_lock)); cthread_worker* Phead_worker = pool->phead;/* the head pointer of a linked list is actually a null pointer at first, so if null, the node address of the build will be assigned to it directly.If (phead_worker! =NULL) {While (phead_worker->next! =NULL) {phead_worker = phead_worker->next;} Phead_worker->next = worker_insert;/* This adds the newly built task node to the end of the list of waiting tasks */}else {pool->phead = worker_insert;} assert (pool->phead! =NULL);/* check here to wait for the list is not empty */pool->cur_queue_size++;/* Synchronize the length of the wait queue to modify the information */pthread_mutex_unlock (& (pool->queue_lock));/* wait for the queue to add a new task, here to wake up the thread to handle, if the wireless path sleep, This statement is invalid */pthread_cond_signal (& (pool->queue_ready));return;}void Pthread_destroy (Void) {If (pool->shutdown) {Return/* prevent multiple calls here */}/* This will destroy the thread pool tag First */pool->shutdown =1;/* Wake up so wait for thread, thread pool to be destroyed */pthread_cond_broadcast (& (pool->queue_ready));/* block wait for thread thread to quit or become a Zombie.int i;For (i =0; I < pool->max_thread_num; i + +) {pthread_join (pool->phead_threadid[i],NULL); }/* Release thread number storage footprint */free (pool->phead_threadid); Pool->phead_threadid =NULL;/* release task waiting queue */cthread_worker *pworker_del = NULL; while (pool->phead! = null) {pworker_del = pool->phead; pool->phead = pool->phead->next; Free (pworker_del); Pworker_del = null;} /* destroy the condition variables and mutexes, and just start forgetting the */pthread_mutex_destroy (& (pool->queue_lock)); pthread_ Cond_destroy (& (pool->queue_ready)); /* release thread pool */free (pool), pool = null; return;} void *my_process (void * Arg) {printf (  "thread is 0x%x, working ont task%d\n", pthread_self (), * (int *) arg); Sleep (1); return;}             

Thread Pool Learning notes

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.