Topic: A simple Linux Thread Pool

Source: Internet
Author: User

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

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.