Simple implementation of thread pool, simple implementation of Thread Pool

Source: Internet
Author: User

Simple implementation of thread pool, simple implementation of Thread Pool

Several Basic thread functions:

Thread-controlled functions
Create: int pthread_create (pthread_t * tidp, const pthread_attr_t * attr, (void *) (* start_rtn) (void *), void * arg );
Terminate its own void pthread_exit (void * retval );
Terminate others: int pthread_cancel (pthread_t tid); the target thread may not be terminated after sending the termination signal. Call the join function to wait.
Blocking and waiting for other threads: int pthread_join (pthread_t tid, void ** retval );

Attribute
Initialization: int pthread_attr_init (pthread_attr_t * attr );
Set the separation status: pthread_attr_setdetachstate (pthread_attr_t * attr, int detachstate)
Destroy attributes: int pthread_attr_destroy (pthread_attr_t * attr );

Synchronous Functions
Mutex lock
Initialization: int pthread_mutex_init (pthread_mutex_t * restrict mutex, const pthread_mutexattr_t * restrict attr );
Destroy lock: int pthread_mutex_destroy (pthread_mutex_t * mutex );
Lock: pthread_mutex_lock (pthread_mutex_t * mutex );
Try to lock: int pthread_mutex_trylock (pthread_mutex_t * mutex );
Unlock: int pthread_mutex_unlock (pthread_mutex_t * mutex );

Condition variable
Initialization: int pthread_cond_init (pthread_cond_t * cv, const pthread_condattr_t * cattr );
Destroy: int pthread_cond_destroy (pthread_cond_t * cond );
Waiting condition: pthread_cond_wait (pthread_cond_t * cond, pthread_mutex_t * mutex)
Notification: pthread_cond_signal (pthread_cond_t * cond); wake up the first thread that calls pthread_cond_wait () and enters sleep

Tool Functions
Comparison thread ID: int pthread_equal (pthread_t t1, pthread_t t2 );
Separation thread: pthread_detach (pthread_t tid );
Self ID: pthread_t pthread_self (void );

 

1 # include <stdio. h> 2 # include <stdlib. h> 3 # include <pthread. h> // multi-threaded header files in linux, non-C standard library, at the end of the compilation, add-lpthread to call the dynamic link library 4 5 // structure of the work linked list 6 typedef struct worker {7 void * (* process) (void * arg ); // working function 8 void * arg; // function parameter 9 struct worker * next; 10} CThread_worker; 11 12 // Thread Pool Structure 13 typedef struct {14 pthread_mutex_t queue_lock; // mutex lock 15 pthread_cond_t queue_ready; // condition variable/semaphore 16 17 CThread_worker * queu E_head; // point to the head node of the Work linked list, which is 18 int cur_queue_size in the critical section; // record the number of jobs in the linked list, 19 20 int max_thread_num in the critical section; // maximum number of threads 21 pthread_t * threadid; // thread ID 22 23 int shutdown; // switch 24} CThread_pool; 25 26 static CThread_pool * pool = NULL; // a thread pool variable 27 int pool_add_worker (void * (* process) (void * arg), void * arg ); // Add work 28 void * thread_routine (void * arg) to the Work linked list; // thread routine 29 30 // thread pool initialization 31 void 32 pool_init (int max_thread_num) 33 {34 int I = 0; 35 36 pool = (CThread_pool *) malloc (sizeof (CThread_pool )); // create thread pool 37 38 pthread_mutex_init (& (pool-> queue_lock), NULL); // mutex lock initialization, the parameter is the lock address 39 pthread_cond_init (& (pool-> queue_ready), NULL); // The Conditional Variable initialization. The parameter is the variable address 40 41 pool-> queue_head = NULL; 42 pool-> cur_queue_size = 0; 43 44 pool-> max_thread_num = max_thread_num; 45 pool-> threadid = (pthread_t *) malloc (max_thread_num * sizeof (p Thread_t); 46 for (I = 0; I <max_thread_num; I ++) {47 pthread_create (& (pool-> threadid [I]), NULL, thread_routine, NULL); // create a thread. The parameter is the thread ID variable address, attribute, routine, parameter 48} 49 50 pool-> shutdown = 0; 51} 52 53 // routine, call the specific function 54 void * 55 thread_routine (void * arg) 56 {57 printf ("starting thread 0x % x \ n", (int) pthread_self ()); 58 while (1) {59 pthread_mutex_lock (& (pool-> queue_lock); // to get the work from the Work linked list, add a mutex lock first. The parameter is the lock address 60 61. While (pool-> cur_queue_size = 0 &&! Pool-> shutdown) {// The linked list is empty 62 printf ("thread 0x % x is waiting \ n", (int) pthread_self ()); 63 pthread_cond_wait (& (pool-> queue_ready), & (pool-> queue_lock); // wait for resources, semaphores are used for notifications. The lock of the second parameter will be released for addition; the lock will be re-applied when the function returns. 64} 65 66 if (pool-> shutdown) {67 pthread_mutex_unlock (& (pool-> queue_lock); // The stop switch is enabled, release the lock and exit the thread 68 printf ("thread 0x % x will exit \ n", (int) pthread_self (); 69 pthread_exit (NULL ); // The parameter is void * 70} 71 72 printf ("thread 0x % x is starting to work \ n", (int) pthread_self ()); 73 74 -- pool-> cur_queue_size; 75 CThread_worker * worker = pool-> queue_head; 76 pool-> queue_head = worker-> next; 77 78 pthread_mutex_u Nlock (& (pool-> queue_lock); // obtain a working instance and release the lock 79 80 81 (* (worker-> process) (worker-> arg ); // do 82 free (worker); 83 worker = NULL; 84} 85 86 pthread_exit (NULL); 87} 88 89 // destroy thread pool 90 int 91 pool_destroy () 92 {93 if (pool-> shutdown) // check whether the stop switch is enabled. if enabled, all threads automatically exit 94 return-1; 95 pool-> shutdown = 1; 96 97 pthread_cond_broadcast (& (pool-> queue_ready); // broadcast, wake up all threads, prepare to exit 98 99 int I; 100 for (I = 0; I <pool -> Max_thread_num; ++ I) 101 pthread_join (pool-> threadid [I], NULL); // The main thread waits for all threads to exit. Only the first parameter of join is not a pointer, the second parameter type is void **. To receive the return value of exit, you must forcibly convert 102 free (pool-> threadid); 103 104 CThread_worker * head = NULL; 105 while (pool-> queue_head! = NULL) {// release the remaining node of the unexecuted work linked list, 106 head = pool-> queue_head; 107 pool-> queue_head = pool-> queue_head-> next; 108 free (head); 109} 110 111 pthread_mutex_destroy (& (pool-> queue_lock); // destroy the lock and the condition variable 112 pthread_cond_destroy (& (pool-> queue_ready )); 113 114 free (pool); 115 pool = NULL; 116 return 0; 117} 118 119 void * 120 myprocess (void * arg) 121 {122 printf ("threadid is 0x % x, working on task % d \ n", (int) pthread_self (), * (in T *) arg); 123 sleep (1); 124 return NULL; 125} 126 127 // Add work 128 int129 pool_add_worker (void * (* process) (void * arg ), void * arg) 130 {131 CThread_worker * newworker = (CThread_worker *) malloc (sizeof (CThread_worker); 132 newworker-> process = process; // The specific working function 133 newworker-> arg = arg; 134 newworker-> next = NULL; 135 136 pthread_mutex_lock (& (pool-> queue_lock )); // lock 137 138 CThread_worker * member = pool-> q Ueue_head; // Insert the end of the linked list to 139 if (member! = NULL) {140 while (member-> next! = NULL) 141 member = member-> next; 142 member-> next = newworker; 143} 144 else {145 pool-> queue_head = newworker; 146} 147 + pool-> cur_queue_size; 148 149 pthread_mutex_unlock (& (pool-> queue_lock); // unlock 150 151 pthread_cond_signal (& (pool-> queue_ready )); // notify a waiting thread 152 return 0; 153} 154 155 int156 main (int argc, char ** argv) 157 {158 pool_init (3 ); // The main thread creates a thread pool. The three threads are 159 int * workingnum = (int *) malloc (sizeof (int) * 10) and 160 int I; 162 for (I = 0; I <10 ;++ I) {163 workingnum [I] = I; 164 pool_add_worker (myprocess, & workingnum [I]); // The main thread is responsible for adding 10 jobs. 165} 166 167 sleep (5); 168 pool_destroy (); // destroy the thread pool 169 free (workingnum ); 170 171 return 0; 172}

 


How to implement a thread pool in java

The simplest method is to use java. util. concurrent. Executors.
Call Executors. newCachedThreadPool () to obtain the buffer Thread Pool
Executors. newFixedThreadPool (int nThreads) to obtain a fixed thread pool

[Switch] Introduction to implementation methods of several open-source Java Web Container thread pools-Tomcat (1)

Resin needs to be purchased from V3.0 for commercial purposes, while the other two are pure open-source. You can download the latest Binary Package and source code from their websites.
As a Web container, it must withstand high traffic volumes and respond to requests from different users at the same time. It can maintain high stability and robustness in harsh environments. In the HTTP server field, ApacheHTTPD is the most efficient and stable, but it can only process static page requests. To support dynamic page requests, you must install the corresponding plug-ins, for example, mod_perl can process Perl scripts, while mod_python can process Python scripts.
The Web containers mentioned above are all HTTP servers written in Java. Of course, they can be embedded in Apache or used independently. Analysis of the methods for processing client requests helps you understand the implementation methods of Java multithreading and thread pools, and lay a solid foundation for designing a powerful multi-threaded server.
Tomcat is the most widely used Java Web Container with powerful functions and high scalability. To improve response speed and efficiency, the latest version of Tomcat (5.5.17) uses Apache Portable Runtime (APR) as the bottom layer and uses various technologies such as Socket and buffer pool in APR, performance is also improved. APR is also the bottom layer of Apache HTTPD. It can be imagined that there are still a lot of mutual use cases for members of the ASF (Apache Software Foundation), although different development languages are used.
Tomcat's thread pool is located in the tomcat-util.jar file and contains two thread pool schemes. Solution 1: Use APR Pool technology and JNI; solution 2: Use ThreadPool implemented by Java. The second type is introduced here. If you want to know APR's Pool technology, you can view the source code of APR.
By default, ThreadPool creates five threads and stores them in a 200-dimension thread array. These threads are started when they are created. Of course, when there is no request, they all process the waiting state (in fact, it is a while loop, and they keep waiting for Y ). If there is a request, the idle thread will be awakened to execute the user's request.
The specific request process is: when the service is started, create a one-dimensional thread array (maxThread = 200), and create Idle threads (minSpareThreads = 5) to wait for user requests at any time. When a user requests, call the threadpool. runIt (ThreadPoolRunnable) method to send an instance to ThreadPool. The instance to be executed must implement the ThreadPoolRunnable interface. ThreadPool first searches for Idle threads. If there are Idle threads, it runs to execute ThreadPoolRunnable. If there is no idle thread and it does not exceed maxThreads, it creates minSpareThreads Idle threads at a time. If maxThreads is exceeded, wait for the idle thread. In short, you need to find a idle thread to use it to execute the instance. Find the thread and remove it from the thread array. Then wake up the idle thread that has been found and use it to run the instance ThreadPoolRunnable ). After running ThreadPoolRunnable, place the thread in the thread array and use it as an idle thread for subsequent use.
It can be seen that the implementation of Tomcat's thread pool is relatively simple, and ThreadPool. java only has 840 lines of code. Use a one-dimensional array to save Idle threads, and create Idle threads at a small pace (5) each time and put them in the thread pool. Remove Idle threads from the array during use, and return them to the thread pool after use.

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.