This paper describes the simple realization method of C + + thread pool in detail in the form of instance. Share for everyone to use for reference. The specific methods are as follows:
First, several basic thread functions:
1. Thread manipulation function:
int Pthread_create (pthread_t *tidp, const pthread_attr_t *attr, (void*) (*START_RTN) (void *), void *arg); Create
void Pthread_exit (void *retval); Terminate itself
int pthread_cancel (pthread_t tid); Terminate the other. The target thread does not necessarily terminate after sending the stop signal, and the join function waits for the
int pthread_join (pthread_t tid, void **retval); Block and wait for other threads
2. Properties:
int Pthread_attr_init (pthread_attr_t *attr); Initializes the property
int pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate);//Set the detach state
int Pthread_attr_ Destroy (pthread_attr_t *attr); Destroying properties
3. Sync function
Mutual exclusion Lock
int Pthread_mutex_init (pthread_mutex_t *restrict Mutex, const pthread_mutexattr_t *restrict attr); Initialize lock
int Pthread_mutex_destroy (pthread_mutex_t *mutex);//Destroy lock
int Pthread_mutex_lock (pthread_mutex_t * Mutex); Lock
int Pthread_mutex_trylock (pthread_mutex_t *mutex);//attempt to lock the non-blocking version int pthread_mutex_unlock with lock
( pthread_mutex_t *mutex); Unlock
4. Condition variable
int Pthread_cond_init (pthread_cond_t *cv, const pthread_condattr_t *cattr); Initialize
int Pthread_cond_destroy (pthread_cond_t *cond); Destroy
int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex); Wait condition
int pthread_cond_signal (pthread_cond_t *cond); Notification, wake up the first call to Pthread_cond_wait () and go to sleep thread
5. Tool function
int pthread_equal (pthread_t t1, pthread_t T2); Compare thread ID
int Pthread_detach (pthread_t tid); Detach Thread
pthread_t pthread_self (void); Self ID
In the preceding code, the thread's cancel and join, and the last tool function, the parameters of these functions are structural variables, the other function parameters are structural variables pointers; Taste, the parameters are pointers, because all need to change the contents of the structure, and the parameters are ordinary variables, you only need to read the content.
Second, thread pool code:
#include <stdio.h> #include <stdlib.h> #include <pthread.h>//linux header files, non-C language standard library, compile-time final add- Lpthread Call dynamic link library//work list structure typedef struct WORKER {void * (*process) (void *arg); work function void *arg;
The parameters of the function struct the worker *next;
}cthread_worker; The structure of the thread pool is typedef struct {pthread_mutex_t queue_lock; Mutual-exclusion lock pthread_cond_t Queue_ready; Condition variable/signal quantity Cthread_worker *queue_head; Point to the head node of the work list, the critical region int cur_queue_size; Record the number of work in the linked list, the critical region int max_thread_num; Maximum number of threads pthread_t *threadid; Thread ID int shutdown;
Switch}cthread_pool; static Cthread_pool *pool = NULL; A thread pool variable int pool_add_worker (void * (*process) (void *arg), void *arg); Responsible for adding work void *thread_routine (void *arg) to the work list;
Thread routines/threads pool initialization void Pool_init (int max_thread_num) {int i = 0; Pool = (Cthread_pool *) malloc (sizeof (Cthread_pool)); Create a thread pool Pthread_mutex_init (& (Pool->queue_lock), NULL); Mutex initialization, parameter is the address of the lock Pthread_cond_init (& pool->Queue_ready), NULL);
The condition variable is initialized, the parameter is variable address pool->queue_head = NULL;
pool->cur_queue_size = 0;
Pool->max_thread_num = Max_thread_num;
Pool->threadid = (pthread_t *) malloc (max_thread_num * sizeof (pthread_t)); for (i = 0; i < Max_thread_num i++) {pthread_create (& (Pool->threadid[i)), NULL, thread_routine, NULL);//Create
Build thread, parameter is thread ID variable address, attribute, routine, parameter} pool->shutdown = 0;
}//routines, call specific work function void *thread_routine (void *arg) {printf ("Starting Thread 0x%x\n", (int) pthread_self ()); while (1) {Pthread_mutex_lock (& (Pool->queue_lock)); To take work from a work list, first add a mutex, the parameter is the lock address while (pool->cur_queue_size = = 0 &&!pool->shutdown) {//The list is empty printf (
"Thread 0x%x is waiting\n", (int) pthread_self ()); Pthread_cond_wait (& (Pool->queue_ready), & (Pool->queue_lock)); Wait for resources, semaphores for notifications.
The lock of the second parameter is freed for addition, and the function is returned with a lock. } if (Pool->shutdown) {Pthread_mutex_unlock (& (Pool->queue_lock)); End switch on, release lock and exit thread Printf ("Thread 0x%x'll exit\n", (int) pthread_self ()); Pthread_exit (NULL);
parameter is void *} printf ("Thread 0x%x are starting to work\n", (int) pthread_self ());
--pool->cur_queue_size;
Cthread_worker *worker = pool->queue_head;
Pool->queue_head = worker->next; Pthread_mutex_unlock (& (Pool->queue_lock)); Obtain a Work Release lock (* (worker->process)) (WORKER->ARG);
Work free (worker);
worker = NULL;
} pthread_exit (NULL);
}//Destroy thread pool int Pool_destroy () {if (Pool->shutdown)//detection end switch is turned on, if open, all threads will automatically exit return-1;
Pool->shutdown = 1; Pthread_cond_broadcast (& (Pool->queue_ready));
broadcasts, wakes all threads, prepares to exit int i; for (i = 0; i < pool->max_thread_num; ++i) Pthread_join (Pool->threadid[i], NULL);
Main thread waits for all threads to exit, only join the first parameter is not a pointer, the second parameter type is void * *, receive the return value of exit, need to cast free (pool->threadid);
Cthread_worker *head = NULL; while (Pool->queue_head!= NULL) {//Free the remaining node head of the not executed work list = Pool->quEue_head;
Pool->queue_head = pool->queue_head->next;
Free (head); } Pthread_mutex_destroy (& (Pool->queue_lock));
Destroy lock and Condition variable Pthread_cond_destroy (& (Pool->queue_ready));
Free (pool);
Pool=null;
return 0;
} void *myprocess (void *arg) {printf ("ThreadID is 0x%x, working on Task%d\n", (int) pthread_self (), * (int*) arg);
Sleep (1);
return NULL; //Add work int pool_add_worker (void * (*process) (void *arg), void *arg) {Cthread_worker *newworker = (Cthread_worker *) m
Alloc (sizeof (Cthread_worker)); newworker->process = process;
The specific work function Newworker->arg = arg;
Newworker->next = NULL; Pthread_mutex_lock (& (Pool->queue_lock)); Lock Cthread_worker *member = pool->queue_head;
Insert the tail of the list if (member!= null) {while (Member->next!= null) member = member->next;
Member->next = Newworker;
else {pool->queue_head = Newworker;
} ++pool->cur_queue_size; Pthread_mutex_unlock ( & (Pool->queue_lock)); Unlock pthread_cond_signal (& (Pool->queue_ready));
Notifies a waiting thread to return 0; int main (int argc, char **argv) {pool_init (3);
Main thread creation thread pool, 3 thread int *workingnum = (int *) malloc (sizeof (int) * 10);
int i;
for (i = 0; i < ++i) {Workingnum[i] = i; Pool_add_worker (Myprocess, &workingnum[i]);
The main thread is responsible for adding work, 10 Work} sleep (5); Pool_destroy ();
Destroy thread pool free (workingnum);
return 0;
}
I hope this article will help you with your C + + programming.