Simple implementation of the C + + thread pool under Linux (add comments on the foreigner code)

Source: Internet
Author: User

As a C + + rookie, the study of the implementation of the code for half a day, found a lot of grammar is not familiar, so added a lot of comments, for reference only. This code mainly by inheriting the Workthread class to implement its own thread code, through the Thread_pool class to manage the thread pool, the thread pool can not achieve dynamic change in the number of threads, there are some limitations. There may still be defects, after all, C + + to encapsulate this thing, resources to release something must be clear, such as vector storage of the base class pointer implementation polymorphism, then how to release the object still need to consider, subsequent I may be further modified to improve the code, the following contribution to their own labor results.

#include <pthread.h> #include <semaphore.h> #include <iostream> #include <vector>using    Namespace Std;/*workerthread Classthis class needs to being sobclassed by the User.*/class workerthread{public:int ID;    Unsigned virtual executethis () {return 0;} Workerthread (int id): ID (ID) {} virtual ~workerthread () {}};/*threadpool class manages all the ThreadPool related Activ Ities. This includes keeping track of the idle threads and synchronizations between all Threads.*/class threadpool{public:threadp    Ool ();    ThreadPool (int maxthreadstemp);    Virtual ~threadpool (); void Destroypool (int maxpollsecs);    BOOL Assignwork (Workerthread *worker);    BOOL Fetchwork (workerthread **worker); void Initializethreads (); static void *threadexecute (void *param);    The function called by the pthread_create () must be statically static pthread_mutex_t Mutexsync;        Static pthread_mutex_t mutexworkcompletion;//Work Complete number of mutex private:int maxthreads;    pthread_cond_t Condcrit;    Sem_t availablework;Sem_t availablethreads;    Vector<workerthread *> Workerqueue;    int TopIndex;    int Bottomindex;int incompletework; int queuesize;};

#include <stdlib.h> #include "threadpool.h" using namespace std;//the static member of the initialization class must be of type and scope, and the static data member must be defined outside the class definition body. Unlike data members that can be initialized with constructors//should be initialized at the time of definition, note the definition, which should be placed in a file containing the non-inline member function definition of the class. Note: Static member functions can only use static variables, non-static without restrictions, static variables must be defined and initialized externally, uninitialized is the default value pthread_mutex_t Threadpool::mutexsync = pthread_mutex_ initializer;pthread_mutex_t threadpool::mutexworkcompletion = Pthread_mutex_initializer; Threadpool::threadpool () {ThreadPool (2);}      Threadpool::threadpool (int maxthreads) {if (MaxThreads < 1) Maxthreads=1;   Pthread_mutex_lock (&mutexsync);   This->maxthreads = MaxThreads;   This->queuesize = MaxThreads;   Workerqueue.resize (MaxThreads, NULL);//Resize the container and initialize the new space with the default constructor TopIndex = 0;   Bottomindex = 0;   incompletework = 0; Sem_init (&availablework, 0, 0);  The work queue semaphore, which indicates that the work has been queued, initially did not work Sem_init (&availablethreads, 0, queuesize); The amount of idle thread semaphore, quisize thread can use Pthread_mutex_unlock (&mutexsync) at the beginning;} Call Pthread_create () to let the thread run, Threadexecute is the static function of the class, because the Pthread_create () Third argument must be a static function VOID Threadpool::initializethreads () {for (int i = 0; i<maxthreads; ++i) {pthread_t tempthread;pthread_create (&   Tempthread, NULL, Threadpool::threadexecute, (void*) this); }}threadpool::~threadpool () {///Because Vector,clear does not really free memory (this is what is done to optimize efficiency), clear actually does is to call destructors (if any) for all objects held in the vector,/    /Then initialize the size of these things so that you feel that all the objects have been erased ...    The actual release of memory is carried out in the destructor of the vector, so once the scope of the vector (such as the function return) is exceeded, all the objects that it holds are destroyed, and then the DEALLOCATE function in the allocator is called to reclaim the memory of the object itself ... Workerqueue.clear ();} void ThreadPool::d estroypool (int maxpollsecs = 2) {while (incompletework>0) {//cout << ' work is still incomplet E= "<< incompletework << endl;sleep (maxpollsecs);} cout << "All done!! wow!    That is a lot of work! "<< Endl;sem_destroy (&availablework); Sem_destroy (&availablethreads);    Pthread_mutex_destroy (&mutexsync); Pthread_mutex_destroy (&mutexworkcompletion);} Assign the person to top and then notify that the task needs to be executed. BOOL Threadpool::assignwork (Workerthread *workerthread) {pthread_mutex_lock (&mutexworkcompletion); Incompletework++;//cout << "assignwork...incomapletework=" << incompletework << Endl;pthread_mutex    _unlock (&mutexworkcompletion), sem_wait (&availablethreads);p thread_mutex_lock (&mutexSync);    Workervec[topindex] = Workerthread;    Workerqueue[topindex] = Workerthread; cout << "Assigning worker[" << workerthread->id << "] address:[" << workerthread << "]    to Queue index ["<< topindex <<"] "<< endl;if (queuesize!=1) TopIndex = (topindex+1)% (queueSize-1); Sem_post (&availablework);p thread_mutex_unlock (&mutexsync); return true;} Once a character has been placed in the queue, it will be notified and then removed from the bottom, returning bool Threadpool::fetchwork (Workerthread **workerarg) {sem_wait (Workerarg) in the &availablework);p Thread_mutex_lock (&mutexsync);    Workerthread * workerthread = Workerqueue[bottomindex]; Workerqueue[bottomindex] = Null;*workerarg = workerthread;if (queuesize!=1) Bottomindex = (bottomIndex+1)% (queueSize-1 ); Sem_post (&availablethreads);p Thread_mutex_unlock (&mutexsync); return true;} Each thread runs a static function entity, and the Executethis method will be inherited from the write, followed by the implementation of the specific thread's work. void *threadpool::threadexecute (void *param) {workerthread *worker = Null;while (((ThreadPool *) param)->fetchwork (            &worker)) {if (worker) {worker->executethis (); cout << "worker[" << worker->id << "]\tdelete address: [" << worker << "]" << end            L            Delete worker;        worker = NULL;        }pthread_mutex_lock (& ((ThreadPool *) param->mutexworkcompletion)); cout << "Thread" << pthread_self () << "has completed a Job!" << Endl; ((ThreadPool *) param)->incompletework--;p thread_mutex_unlock (& (((ThreadPool *) param) mutexworkcompletion));} return 0;}

#include <iostream> #include "threadpool.h" using namespace std; #define Iterations 20class Sampleworkerthread: Public workerthread{public:int id;unsigned Virtual Executethis () {//Instead of sleep () we could do anytime consuming w Ork here.//Using Threadpools is advantageous if the work to be do is really time consuming.    (atleast 1 or 2 seconds) cout<< "This is sampleworkerthread sleep 2s" <<endl;sleep (2); return (0);} Sampleworkerthread (int id): workerthread (ID), ID (ID) {//cout << ' Creating sampleworkerthread ' << i    D << "\ t address=" << this << Endl; } ~sampleworkerthread () {//cout << "Deleting sampleworkerthread" << ID << "\ t address=" &l    t;< this << Endl; }};int Main (int argc, char **argv) {cout<< "Thread Pool" <<endl;    threadpool* Mypool = new ThreadPool,//pthread_create () executes, starts waiting for task assignment mypool->initializethreads ();//used to calculate the time interval. time_t t1=time (NULL);//Assign specific work-to-linePool for (unsigned int i=0;i<iterations;i++) {sampleworkerthread* mythreathreadexecuted = new Sampleworkerthread (i); Mypool->assignwork (mythreathreadexecuted);}    Destroy the money waiting for all threads to end, waiting interval is 2 seconds.    Mypool->destroypool (2);    time_t t2=time (NULL);    cout << t2-t1 << "seconds elapsed\n" << endl;delete Mypool; return 0;}

Under Ubuntu 12.04 run successfully, the compile command is as follows: g++-G main.cpp thread_pool.cpp-o Thread_pool-lpthread

Simple implementation of the C + + thread pool under Linux (add comments on the foreigner code)

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.