Linux system programming-thread pool

Source: Internet
Author: User

Thread Pool Fundamentals

In the traditional server structure, there is always a total listener thread listening to there is no new user connection server, whenever a new user enters, the server opens a new thread user to process the user's packet. This thread only serves this user, and the server destroys the thread after the user has closed the connection to the server side. (See concurrent servers for more details on concurrent servers.)


Frequently, however , the creation and destruction of threads consumes greatly the resources of the system, and in the case of a large number of users, the system wastes a significant amount of time and resources in order to open and destroy threads. The thread pool provides a solution to a large number of external users and server limited resources contradictions.


The thread pool and the traditional one of the users corresponding to a threading method, its basic idea is to open up some threads in memory at the beginning of the program, the number of threads is fixed, they form a class alone, shielding the external operations, and the server only need to send the packet to the thread pool. When a new client request arrives, instead of creating a new thread for its service, instead selects an idle thread from the pool to service the new customer request, and after the service is finished, the thread enters the pool of idle threads. If no thread is idle, the packet is temporarily accumulated, waiting for the thread pool to be idle for later processing. By reusing a thread object that already exists for multiple tasks, the overhead of creating and destroying thread objects is reduced. When the client requests, the thread object already exists, can increase the response time of the request, thus overall improve the performance of the system service.


thread Pool Application instance

In general, implementing a thread pool consists mainly of the following components:

1) Thread Manager: Used to create and manage thread pools.


2) worker thread: The thread in the thread pool that actually performs the task. When the thread is initialized, a fixed number of threads are pre-created in the pool, and these initialized threads are generally idle, typically taking up less CPU and consuming less memory space.


3) Task interface: the interface that each task must implement, when there are executable tasks in the thread pool's task queue, is executed by the idle worker thread (the thread's idle and busy is implemented by mutual exclusion), the task is abstracted out to form an interface, and the thread pool is independent of the specific task.


4) Task queue: Used to store no processing tasks, provide a buffer mechanism, the implementation of this structure has several methods, commonly used is the queue, mainly the use of FIFO principle, the other is linked to the list of data structures, you can dynamically allocate memory space for it, the application is more flexible, this tutorial is used in the linked list.


when do I need to create a thread pool? simply put, if an application needs to create and destroy threads frequently, and the task executes in a very short time, the overhead of creating and destroying threads is not negligible, and this is the opportunity for the thread pool to appear. If the thread creation and destruction times are negligible compared to the execution time of the task, there is no need to use the thread pool.


The thread pool implementation sample code is as follows:


Example code for Thread_pool.h:

#ifndef __thread_pool_h__#define __thread_pool_h__#include <pthread.h>/************************************ Task callback function, you can also modify the *********************************************************** as needed /typedef void * (*pool_task_f) (void *arg);/************************************************************* Task handle *********************************************************************/typedef struct _TASK{POOL_     Task_f process;/* callback function, the task runtime will call this function, note can also be declared as other forms of */void *arg; /* The parameter of the callback function */struct _task *next;} pool_task;/********************************************************************** thread pool handle ************************ /typedef struct{pthread_t *threadid;/* thread number */int threads_limit;/*    Number of active threads allowed in the thread pool */int destroy_flag;/* whether to destroy the thread pool, 0 destroy, 1 do not destroy */pool_task *queue_head; /* list structure, the number of tasks in the thread pool waiting for tasks */int task_in_queue;/* current queue */pthread_mutex_t queue_lock;/* lock */pthread_cond_t queue_ready;/* Conditional variable */}pool_t;/*******************Function: Initialize thread pool structure and create threads * Parameters: Pool: Thread pool handle Threads_limit: Number of threads in thread pools * return value: No *********************************************************************/void pool_init (pool_t *pool, int threads_ limit);/********************************************************************** function: Destroys the thread pool and waits for tasks in the queue to be no longer executed. But the running thread will continue to run and then exit the * parameter: thread pool handle * Return value: Success: 0, failure non-0**************************************************************** /int pool_uninit (pool_t *pool);/********************************************************************** function: Add a task to the thread pool * parameters: Pool: Thread pool handle Process: Task handler arg: task parameter * return value: 0********************************************************* /int Pool_add_task (pool_t *pool, pool_task_f process, void *arg); #endif


example code for THREAD_POOL.C:
#include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <assert.h> #include " Thread_pool.h "static void *pool_thread_server (void *arg);/******************************************************* Function: Initialize thread pool structure and create threads * Parameters: Pool: Thread pool handle Threads_limit: Number of threads in thread pools * return value: No *********************************** /void Pool_init (pool_t *pool, int threads_limit) {pool->threads_limit = Threads_ Limit;pool->queue_head = Null;pool->task_in_queue = 0;pool->destroy_flag = 0;/* Creates a space to hold the thread ID */pool-> ThreadID = (pthread_t *) calloc (threads_limit, sizeof (pthread_t)); int i = 0;/* initialize mutex and condition variable */pthread_mutex_init (& ( Pool->queue_lock), NULL);p Thread_cond_init (& (Pool->queue_ready), NULL);/* Loops Create Threads_limit threads */for (i = 0 ; i < Threads_limit; i++) {pthread_create (& (Pool->threadid[i]), NULL, pool_thread_server, pool);} return;} /********************************************************************** function: Destroys the thread pool, waiting for tasks in the queue to no longer be executed, butThe running thread will continue to run and then exit the * parameter: thread pool handle * Return value: Success: 0, failure non-0****************************************************************** /int pool_uninit (pool_t *pool) {pool_task *head = Null;int i;pthread_mutex_lock (& (Pool->queue_lock)); if ( Pool->destroy_flag)/* Prevent two calls */return-1;pool->destroy_flag = 1;pthread_mutex_unlock (& (Pool->queue_ lock);/* Wake up all waiting threads, thread pool to destroy */pthread_cond_broadcast (& (Pool->queue_ready));/* block wait thread to exit, or zombie */for (i = 0; i < pool->threads_limit; i++) Pthread_join (Pool->threadid[i], NULL), free (pool->threadid);/* Destroy wait Queue */pthread_mutex_lock (& (pool- >queue_lock)); while (pool->queue_head! = NULL) {head = Pool->queue_head;pool->queue_head = Pool->queue_ Head->next;free (head);} Pthread_mutex_unlock (& (Pool->queue_lock));/* condition variable and mutex do not forget to destroy */pthread_mutex_destroy (& (Pool->queue_ Lock));p Thread_cond_destroy (& (Pool->queue_ready)); return 0;} /********************************************************************** function: Add a task to the task queue * parameters:p ool: Thread pool handle Process: Task handler arg: task parameter * return value: No *********************************************************************/ static void Enqueue_task (pool_t *pool, pool_task_f process, void *arg) {pool_task *task = null;pool_task *member = null;pth Read_mutex_lock (& (Pool->queue_lock)); if (Pool->task_in_queue >= pool->threads_limit) {printf ("task _in_queue > threads_limit!\n ");p Thread_mutex_unlock (& (Pool->queue_lock)); return;} Task = (Pool_task *) calloc (1, sizeof (Pool_task)); assert (Task! = NULL); task->process = Process;task->arg = arg; Task->next = Null;pool->task_in_queue++;member = pool->queue_head;if (member! = NULL) {while (Member->next!) = NULL)/* Joins the task to the last position of the task chain. */member = Member->next;member->next = task;} Else{pool->queue_head = task;/* If it is the first task, point to the head */}printf ("\ttasks%d\n", pool->task_in_queue);/* Wait for a task in the queue, Wake up a wait thread */pthread_cond_signal (& (Pool->queue_ready));p Thread_mutex_unlock (& (Pool->queue_lock));} /***************************Function: Remove a task from the task queue * Parameters: thread pool handle * Return value: Task handle ********************************** /static pool_task *dequeue_task (pool_t *pool) {Pool_task *task = Null;pthread_ Mutex_lock (& (Pool->queue_lock));/* Determines if the thread pool is to be destroyed */if (Pool->destroy_flag) {Pthread_mutex_unlock (& ( Pool->queue_lock));p rintf ("Thread 0x%lx would be destroyed\n", pthread_self ());p thread_exit (NULL);} /* If the wait queue is 0 and the thread pool is not destroyed, the blocking state */if (Pool->task_in_queue = = 0) {while ((Pool->task_in_queue = = 0) && (!pool- >destroy_flag) {printf ("Thread 0x%lx is waitting\n", pthread_self ());/* Note: pthread_cond_wait is an atomic operation that will be unlocked before waiting. Wake-Up Lock */pthread_cond_wait (& (Pool->queue_ready), & (Pool->queue_lock));}} else{/* waits for Queue length minus 1, and takes out the first element in the queue */pool->task_in_queue--;task = Pool->queue_head;pool->queue_head = task-> next;printf ("Thread 0x%lx received a task\n", pthread_self ());} Pthread_mutex_unlock (& (Pool->queue_lock)); return task;} /**************Function: Add a task to the thread pool * parameters: Pool: Thread pool handle Process: Task handler arg: task parameter * return value : 0*********************************************************************/int pool_add_task (pool_t *pool, Pool_task _f process, void *arg) {enqueue_task (pool, process, arg); return 0;} /********************************************************************** function: Thread pool Service Program * Parameters: Slightly * return value: Slightly ****************** /static void *pool_thread_server (void *arg) {pool_t *pool = NULL; Pool = (pool_t *) Arg;while (1) {Pool_task *task = Null;task = Dequeue_task (pool);/* Call the callback function to perform task */if (Task! = NULL) {printf ("t Hread 0X%LX is busy\n ", pthread_self ()); task->process (Task->arg); free (task); task = NULL;}} /* This sentence should be an unreachable */pthread_exit (NULL); return NULL;}

here is the test code:

#include <stdio.h> #include <unistd.h> #include "thread_pool.h" void *task_test (void *arg) {printf ("\t\ Tworking on Task%d\n ", (int) arg), sleep (1),/* Rest one second, extend the execution time of the task */return NULL;} void Thread_pool_demo (void) {pool_t Pool;int i = 0;pool_init (&pool, 2);//Initializes a thread pool, which creates 2 threads sleep (1); for (i = 0; i < 5 ; i++) {sleep (1);p ool_add_task (&pool, Task_test, (void *) i);//Add a task}sleep (4);p ool_uninit (&pool);//delete thread pool}int Main (int argc, char *argv[]) {  thread_pool_demo (); return 0;}

The results of the operation are as follows:




For this tutorial sample code download please click here.


Reference: http://blog.csdn.net/hubi0952

Linux system programming-thread pool

Related Article

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.