Thread Pool
: In short, the thread pool
A batch of threads are created in advance to conveniently and quickly process received services. Compared with a traditional task, a thread is created to process the task in real time, which saves the thread creation and recovery overhead, and provides faster response and efficiency.
Higher.
In Linux, the POSIX thread library is used. First, several common functions are introduced:
1. Create and cancel functions in the thread
Pthread_create
Create
Pthread_join
Merge thread
Pthread_cancel
Cancel thread
2. Thread Synchronization Functions
Pthread_mutex_lock
Pthread_mutex_unlock
Pthread_cond_signal
Pthread_cond_wait
For more information about functions, see the man manual.
Implementation of thread pool:
The implementation of the thread pool is mainly divided into three parts: creating a thread, adding a task to the thread pool, and processing a task from the task queue.
There are two main classes for implementation: ctask and cthreadpool.
/**
Class for executing the task, set the task data and execute
**/
Class ctask <br/>{< br/> protected: <br/> string m_strtaskname; // Task Name <br/> void * m_ptrdata; // data of the task to be executed <br/> Public: <br/> ctask () {}< br/> ctask (string taskname) <br/>{< br/> This-> m_strtaskname = taskname; <br/> m_ptrdata = NULL; <br/>}< br/> virtual int run () = 0; <br/> void setdata (void * data); // set task data <br/>}; <br/>
A task class is a virtual class. All tasks must be inherited from the ctask class.
To implement the run interface, the run interface must implement the logic of the specific parsing task. M_ptrdata is a pointer to the task data. It can be a simple data type or a custom complex data type.
Data type.
Thread Pool class
/**
Thread Pool
**/
Class cthreadpool <br/>{< br/> PRIVATE: <br/> vector <ctask *> m_vectasklist; // task list <br/> int m_ithreadnum; // Number of threads started in the thread pool <br/> static vector <pthread_t> m_vecidlethread; // set of currently Idle threads <br/> static vector <pthread_t> m_vecbusythread; // set of threads currently being executed <br/> static pthread_mutex_t m_pthreadmutex; // thread synchronization lock <br/> static pthread_cond_t m_pthreadcond; // condition variable for thread synchronization <br/> protected: <br/> static void * threadfunc (void * threaddata ); // The thread function of the new thread <br/> static int movetoidle (pthread_t tid); // After the thread is executed, put yourself in the idle thread <br/> static int movetobusy (pthread_t tid); // move yourself into the busy thread <br/> int create (); // create all threads <br/> Public: <br/> cthreadpool (INT threadnum); <br/> int addtask (ctask * task ); // Add the task to the thread pool <br/> int stopall (); <br/>}; <br/>
After a thread pool object is created, start a batch of threads and put all threads into the idle list. When a task arrives, a thread extracts the task and processes it.
Thread locks and condition variables are used for synchronization between threads.
This class has two external interfaces:
The addtask function adds a task to the task list of the thread pool and notifies the thread to process the task. When the task arrives, place the task in the m_vectasklist task list and use
Pthread_cond_signal wake up a thread for processing.
The stopall function stops all threads.
**************************************** * ******* <Br/> code: <br/> xxx cthread. h </P> <p> # ifndef _ cthread <br/> # DEFINE _ cthread <br/> # include <vector> <br/> # include <string> <br/> # include <pthread. h> <br/> using namespace STD; <br/>/** <br/> class for executing a task, set task data and execute <br/> **/<br/> class ctask <br/> {<br/> protected: <br/> string m_strtaskname; // Task Name <br/> void * m_ptrdata; // data of the task to be executed <br/> publi C: <br/> ctask () {}< br/> ctask (string taskname) <br/>{< br/> This-> m_strtaskname = taskname; <br/> m_ptrdata = NULL; <br/>}< br/> virtual int run () = 0; <br/> void setdata (void * data ); // set task data <br/> }; <br/>/** <br/> thread pool <br/> **/<br/> class cthreadpool <br/>{< br/> PRIVATE: <br/> vector <ctask *> m_vectasklist; // task list <br/> int m_ithreadnum; // Number of threads started in the thread pool <br/> static vector <pthread_t> m_vecidlethread; // A set of Idle threads <br/> static vector <pthread_t> m_vecbusythread; // a set of currently running threads <br/> static pthread_mutex_t m_pthreadmutex; // thread synchronization lock <br/> static pthread_cond_t m_pthreadcond; // condition variable for thread synchronization <br/> protected: <br/> static void * threadfunc (void * threaddata ); // The thread function of the new thread <br/> static int movetoidle (pthread_t tid); // After the thread is executed, put yourself into the idle thread <br/> static int movetobusy (pthread_t tid); // move yourself into the busy thread <br/> int create (); // Create all threads <br/> Public: <br/> cthreadpool (INT threadnum); <br/> int addtask (ctask * task ); // Add the task to the thread pool <br/> int stopall (); <br/> }; <br/> # endif </P> <p> class implementation: <br/> xxx cthread. CPP </P> <p> # include "cthread. H "<br/> # include <string> <br/> # include <iostream> <br/> using namespace STD; <br/> void ctask :: setdata (void * Data) <br/>{< br/> m_ptrdata = data; <br/>}< br/> vector <pthread_t> cthr Eadpool: m_vecbusythread; <br/> vector <pthread_t> cthreadpool: m_vecidlethread; <br/> export cthreadpool: m_pthreadmutex = merge; <br/> pthread_cond_t cthreadpool :: m_pthreadcond = pthread_cond_initializer; <br/> cthreadpool: cthreadpool (INT threadnum) <br/>{< br/> This-> m_ithreadnum = threadnum; <br/> Create (); <br/>}< br/> int cthreadpool: movetoidle (pthread_t tid) <br/> {< Br/> vector <pthread_t>: iterator busyiter = m_vecbusythread.begin (); <br/> while (busyiter! = M_vecbusythread.end () <br/>{< br/> If (TID = * busyiter) <br/>{< br/> break; <br/>}< br/> busyiter ++; <br/>}< br/> m_vecbusythread.erase (busyiter); <br/> m_vecidlethread.push_back (TID ); <br/> return 0; <br/>}< br/> int cthreadpool: movetobusy (pthread_t tid) <br/>{< br/> vector <pthread_t> :: iterator idleiter = m_vecidlethread.begin (); <br/> while (idleiter! = M_vecidlethread.end () <br/>{< br/> If (TID = * idleiter) <br/>{< br/> break; <br/>}< br/> idleiter ++; <br/>}< br/> m_vecidlethread.erase (idleiter); <br/> m_vecbusythread.push_back (TID ); <br/> return 0; <br/>}< br/> void * cthreadpool: threadfunc (void * threaddata) <br/>{< br/> pthread_t tid = pthread_self (); <br/> while (1) <br/>{< br/> pthread_mutex_lock (& m_pthreadmutex ); <br/> pthread_cond_wa It (& m_pthreadcond, & m_pthreadmutex); <br/> cout <"TID:" <TID <"run" <Endl; <br/> // get task <br/> vector <ctask *> * tasklist = (vector <ctask *> *) threaddata; <br/> vector <ctask *>:: iterator iter = tasklist-> begin (); <br/> while (ITER! = Tasklist-> end () <br/>{</P> <p> movetobusy (TID); <br/> break; <br/>}< br/> ctask * task = * ITER; <br/> tasklist-> erase (ITER); <br/> pthread_mutex_unlock (& m_pthreadmutex ); <br/> cout <"idel thread number:" <cthreadpool: m_vecidlethread.size () <Endl; <br/> cout <"busy thread Number: "<cthreadpool: m_vecbusythread.size () <Endl; <br/> // cout <" task to be run: "<tasklist-> size () <End L; <br/> task-> Run (); </P> <p> // cout <"cthread: thread work" <Endl; <br/> cout <"TID:" <TID <"idle" <Endl; </P> <p >}< br/> return (void *) 0; <br/>}< br/> int cthreadpool: addtask (ctask * task) <br/>{< br/> This-> m_vectasklist.push_back (task ); <br/> pthread_cond_signal (& m_pthreadcond); <br/> return 0; <br/>}< br/> int cthreadpool: Create () <br/> {<br/> for (INT I = 0; I <m_ithreadnum; I ++) <br />{< Br/> pthread_t tid = 0; <br/> pthread_create (& tid, null, threadfunc, & m_vectasklist); <br/> m_vecidlethread.push_back (TID ); <br/>}< br/> return 0; <br/>}< br/> int cthreadpool: stopall () <br/>{< br/> vector <pthread_t>: iterator iter = m_vecidlethread.begin (); <br/> while (ITER! = M_vecidlethread.end () <br/>{< br/> pthread_cancel (* ITER); <br/> pthread_join (* ITER, null); <br/> ITER ++; <br/>}< br/> iter = m_vecbusythread.begin (); <br/> while (ITER! = M_vecbusythread.end () <br/>{< br/> pthread_cancel (* ITER); <br/> pthread_join (* ITER, null); <br/> ITER ++; <br/>}</P> <p> return 0; <br/>}< br/> simple example: <br/> xxx test. CPP <br/> # include "cthread. H "<br/> # include <iostream> <br/> using namespace STD; <br/> class cworktask: Public ctask <br/>{< br/> public: <br/> cworktask () <br/>{}< br/> int run () <br/>{< br/> cout <(char *) this-> m_ptrdata <Endl; <br/> sleep (10); <br/> return 0; <br/>}< br/> }; <br/> int main () <br/> {<br/> cworktask taskobj; <br/> char sztmp [] = "This is the first thread running, haha success "; <br/> taskobj. setdata (void *) sztmp); <br/> cthreadpool threadpool (10); <br/> for (INT I = 0; I <11; I ++) <br/>{< br/> threadpool. addtask (& taskobj); <br/>}< br/> while (1) <br/>{< br/> sleep (120 ); <br/>}< br/> return 0; <br/>}< br/>
Reprinted from: http://www.javaeye.com/topic/345688