Linux thread pool (C language description)-mutex volume + Conditional Variable Synchronization

Source: Internet
Author: User

The overhead of creating threads or processes is very high. To prevent frequent thread creation and improve program running efficiency, a thread pool is usually set up for multi-thread program scheduling.

The following program is a complete thread pool implementation, mainly using mutex and conditional variables for synchronization
 
First define the header file threadpool. h

This file defines the data structure and all functions of the thread pool.

# Ifndef threadpool_h _ # define threadpool_h _ # include <stdio. h> # include <stdlib. h> # include <unistd. h> # include <pthread. h>/*** thread Body Data Structure */typedef struct runner {void (* callback) (void * Arg); // callback function pointer void * ARG; // The parameter struct runner * Next;} thread_runner of the callback function;/*** thread pool Data Structure */typedef struct {pthread_mutex_t mutex; // mutex volume pthread_cond_t cond; // condition variable thread_runner * runner_head; // The thread_runner * runner_tail header pointer of all waiting tasks in the thread pool; // The Int shutdown pointer of all waiting tasks in the thread pool; // whether the thread pool destroys pthread_t * threads; // All threads int max_thread_size; // The number of active threads allowed in the thread pool} thread_pool; /*** thread body */void run (void * Arg);/*** initialize thread pool * parameter: * Pool: dynamic pointer to the valid address of the thread pool structure * max_thread_size: Maximum number of threads */void threadpool_init (thread_pool * Pool, int max_thread_size ); /*** Add a task to the thread pool * parameter: * Pool: Dynamic pointer pointing to the valid address of the thread pool structure * callback: thread callback function * Arg: callback function parameter */void threadpool_add_runner (thread_pool * Pool, void (* callback) (void * Arg), void * Arg);/*** destroy thread pool * parameter: * ppool: the dynamic pointer address (second-level pointer) pointing to the valid address of the thread pool structure. The memory is released after destruction. The pointer is null */void threadpool_destroy (thread_pool ** ppool); # endif


Then the function implements threadpool. h.

This file implements the Function Definition of threadpool. h.

# Include "threadpool. H "# define debug 1/*** thread body */void run (void * Arg) {thread_pool * Pool = (thread_pool *) ARG; while (1) {// lock pthread_mutex_lock (& (pool-> mutex); # ifdef debug printf ("Run-> locked \ n "); # endif // If the waiting queue is 0 and the thread pool is not destroyed, it is blocked. While (pool-> runner_head = NULL &&! Pool-> shutdown) {pthread_cond_wait (& (pool-> Cond), & (pool-> mutex) ;}// if the thread pool has been destroyed if (pool-> shutdown) {// unlock pthread_mutex_unlock (& (pool-> mutex); # ifdef debug printf ("Run-> unlocked and thread exit \ n "); # endif pthread_exit (null);} // retrieve the thread_runner * runner = pool-> runner_head; pool-> runner_head = runner-> next; // unlock pthread_mutex_unlock (& (pool-> mutex); # ifdef debug printf ("Run-> unlocked \ N "); # endif // call the callback function to execute tasks (runner-> callback) (runner-> Arg); free (runner); runner = NULL; # ifdef debug printf ("Run-> runned and free runner \ n"); # endif} pthread_exit (null);}/*** initialize thread pool * parameter: * Pool: dynamic pointer to the valid address of the thread pool structure * max_thread_size: Maximum number of threads */void threadpool_init (thread_pool * Pool, int max_thread_size) {// initialize the mutex pthread_mutex_init (& (pool-> mutex), null); // initialize the condition variable pthread_cond_init (& (pool-> Cond), nu Ll); pool-> runner_head = NULL; pool-> runner_tail = NULL; pool-> max_thread_size = max_thread_size; pool-> shutdown = 0; // create all isolated thread pools-> threads = (pthread_t *) malloc (max_thread_size * sizeof (pthread_t); int I = 0; for (I = 0; I <max_thread_size; I ++) {pthread_attr_t ATTR; pthread_attr_init (& ATTR); trim (& ATTR, pthread_create_detached); pthread_create (& (pool-> threads [I]), & ATTR, (void *) Run, (void *) pool) ;}# ifdef debug printf ("threadpool_init-> Create % d detached thread \ n", max_thread_size ); # endif}/*** add task * parameter to thread pool: * Pool: Dynamic pointer pointing to valid address of Thread Pool Structure * callback: thread callback function * Arg: callback function parameters */void threadpool_add_runner (thread_pool * Pool, void (* callback) (void * Arg), void * Arg) {// construct a new task thread_runner * newrunner = (thread_runner *) malloc (sizeof (thread_runner); newrunner-> callbac K = callback; newrunner-> Arg = ARG; newrunner-> next = NULL; // lock pthread_mutex_lock (& (pool-> mutex )); # ifdef debug printf ("threadpool_add_runner-> locked \ n"); # endif // Add the task to the waiting queue if (pool-> runner_head! = NULL) {pool-> runner_tail-> next = newrunner; pool-> runner_tail = newrunner;} else {pool-> runner_head = newrunner; pool-> runner_tail = newrunner ;} // unlock pthread_mutex_unlock (& (pool-> mutex); # ifdef debug printf ("threadpool_add_runner-> unlocked \ n "); # endif // wake up a waiting thread pthread_cond_signal (& (pool-> Cond )); # ifdef debug printf ("threadpool_add_runner-> Add a runner and wakeup a waiting thread \ n"); # endi F}/*** destroy thread pool * parameter: * ppool: Dynamic pointer address pointing to the valid address of the thread pool structure (second-level pointer) */void threadpool_destroy (thread_pool ** ppool) {thread_pool * Pool = * ppool; // prevents the IF (! Pool-> shutdown) {pool-> shutdown = 1; // wake up all the waiting threads. The thread pool must destroy pthread_cond_broadcast (& (pool-> Cond )); // wait until all threads stop sleep (1); # ifdef debug printf ("threadpool_destroy-> wakeup all waiting threads \ n "); # endif // recycle space free (pool-> threads); // destroy the waiting queue thread_runner * head = NULL; while (pool-> runner_head! = NULL) {head = pool-> runner_head; pool-> runner_head = pool-> runner_head-> next; free (head );} # ifdef debug printf ("threadpool_destroy-> All runners freed \ n "); # endif/* do not forget to destroy condition variables and mutex */pthread_mutex_destroy (& (pool-> mutex); pthread_cond_destroy (& (pool-> Cond )); # ifdef debug printf ("threadpool_destroy-> mutex and cond destoryed \ n"); # endif free (pool); (* ppool) = NULL; # ifdef debug printf ("threadpool_destroy-> pool freed \ n"); # endif }}

The above is the complete implementation of the line city pool

Let's write a test program.

#include "threadpool.h"void threadrun(void* arg){ int *i = (int *) arg; printf("%d\n", *i);}int main(void){ thread_pool *pool = malloc(sizeof(thread_pool)); threadpool_init(pool, 2); int i; int tmp[3]; for (i = 0; i < 3; i++) {  tmp[i] = i;  threadpool_add_runner(pool, threadrun, &tmp[i]); } sleep(1); threadpool_destroy(&pool); printf("main-> %p\n",pool); printf("main-> test over\n"); return 0;}

This function creates a thread pool, which contains two threads, and then adds three tasks to the thread pool.

At the end, the pointer address of the thread pool is printed (mainly to check the state after the thread pool is destroyed)

The running result is as follows:

Main debugging information output,
It is worth noting that the penultimate line is "Main-> (NiL )"
It indicates that after the thread pool is destroyed, the pointer pointing to the thread pool is null (that is why the threadpool_destory function uses the second-level pointer)

Address: http://blog.163.com/sean_zwx/blog/static/169032755201232461650707/

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.