C ++ Thread Pool

Source: Internet
Author: User

Thread Pool: in short, a thread pool is a batch of threads 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 overhead of thread creation and collection, and provides faster response and higher efficiency.

In Linux, the POSIX thread library is used. First, several common functions are introduced:
1. Create and cancel functions in the thread
Pthread_create creation thread
Pthread_join wait for the thread to end
Pthread_cancel cancel thread

2. Thread Synchronization Functions

Pthread_mutex_lock
Pthread_mutex_unlock

Pthread_cond_signal
Pthread_cond_wait semaphore

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
**/
C ++ code

Class ctask
{
Protected:
String m_strtaskname; // Task Name
Void * m_ptrdata; // data of the task to be executed
Public:
Ctask (){}
Ctask (string taskname)
{
This-> m_strtaskname = taskname;
M_ptrdata = NULL;
}
Virtual int run () = 0;
Void setdata (void * data); // sets the task data
};

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 task data. It can be a simple data type or a custom complex data type.

 

Thread Pool class

/**
Thread Pool
**/
C ++ code

Class cthreadpool
{
PRIVATE:
Vector <ctask *> m_vectasklist; // task list
Int m_ithreadnum; // Number of threads started in the thread pool
Static vector <pthread_t> m_vecidlethread; // a set of Idle threads.
Static vector <pthread_t> m_vecbusythread; // a set of threads currently being executed
Static pthread_mutex_t m_pthreadmutex; // thread synchronization lock
Static pthread_cond_t m_pthreadcond; // condition variable for Thread Synchronization
Protected:
Static void * threadfunc (void * threaddata); // The thread function of the new thread.
Static int movetoidle (pthread_t tid); // After the thread is executed, put itself into the idle thread
Static int movetobusy (pthread_t tid); // move it to a busy thread
Int create (); // create all threads
Public:
Cthreadpool (INT threadnum );
Int addtask (ctask * task); // Add the task to the thread pool.
Int stopall ();
};

After a thread pool object is created, start a batch of threads and put all threads into the idle list. When a task exists, a thread retrieves the task and processes it.

Thread locks and condition variables are used for synchronization between threads.
This class has two external interfaces:
1. 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 wake up a thread with pthread_cond_signal for processing.

2. The stopall function stops all threads.

CPP Code

Cthread. h
# Ifndef _ cthread
# DEFINE _ cthread
# Include <vector>
# Include <string>
# Include <pthread. h>

Using namespace STD;

/**
Class for executing the task, set the task data and execute
**/
Class ctask
{
Protected:
String m_strtaskname; // Task Name
Void * m_ptrdata; // data of the task to be executed
Public:
Ctask (){}
Ctask (string taskname)
{
This-> m_strtaskname = taskname;
M_ptrdata = NULL;
}
Virtual int run () = 0;
Void setdata (void * data); // sets the task data
};

/**
Thread Pool
**/

Class cthreadpool
{
PRIVATE:
Vector <ctask *> m_vectasklist; // task list
Int m_ithreadnum; // Number of threads started in the thread pool
Static vector <pthread_t> m_vecidlethread; // a set of Idle threads.
Static vector <pthread_t> m_vecbusythread; // a set of threads currently being executed
Static pthread_mutex_t m_pthreadmutex; // thread synchronization lock
Static pthread_cond_t m_pthreadcond; // condition variable for Thread Synchronization
Protected:
Static void * threadfunc (void * threaddata); // The thread function of the new thread.
Static int movetoidle (pthread_t tid); // After the thread is executed, put itself into the idle thread
Static int movetobusy (pthread_t tid); // move it to a busy thread
Int create (); // create all threads
Public:
Cthreadpool (INT threadnum );
Int addtask (ctask * task); // Add the task to the thread pool.
Int stopall ();
};
# Endif

Cthread. cpp

# Include "cthread. H"
# Include <string>
# Include <iostream>
Using namespace STD;

Void ctask: setdata (void * Data)
{
M_ptrdata = data;
}

Vector <pthread_t> cthreadpool: m_vecbusythread;
Vector <pthread_t> cthreadpool: m_vecidlethread;
Pthread_mutex_t cthreadpool: m_pthreadmutex = pthread_mutex_initializer;
Pthread_cond_t cthreadpool: m_pthreadcond = pthread_cond_initializer;

Cthreadpool: cthreadpool (INT threadnum)
{
This-> m_ithreadnum = threadnum;
Create ();
}

Int cthreadpool: movetoidle (pthread_t tid)
{
Vector <pthread_t>: iterator busyiter = m_vecbusythread.begin ();
While (busyiter! = M_vecbusythread.end ())
{
If (TID = * busyiter)
{
Break;
}
Busyiter ++;
}
M_vecbusythread.erase (busyiter );
M_vecidlethread.push_back (TID );
Return 0;
}

Int cthreadpool: movetobusy (pthread_t tid)
{
Vector <pthread_t>: iterator idleiter = m_vecidlethread.begin ();
While (idleiter! = M_vecidlethread.end ())
{
If (TID = * idleiter)
{
Break;
}
Idleiter ++;
}
M_vecidlethread.erase (idleiter );
M_vecbusythread.push_back (TID );
Return 0;
}

Void * cthreadpool: threadfunc (void * threaddata)
{
Pthread_t tid = pthread_self ();
While (1)
{
Pthread_mutex_lock (& m_pthreadmutex );
Pthread_cond_wait (& m_pthreadcond, & m_pthreadmutex );
Cout <"TID:" <TID <"run" <Endl;
// Get task
Vector <ctask *> * tasklist = (vector <ctask *> *) threaddata;
Vector <ctask * >:: iterator iter = tasklist-> begin ();
While (ITER! = Tasklist-> end ())
{
Movetobusy (TID );
Break;
}
Ctask * task = * ITER;
Tasklist-> erase (ITER );
Pthread_mutex_unlock (& m_pthreadmutex );
Cout <"idel thread number:" <cthreadpool: m_vecidlethread.size () <Endl;
Cout <"busy thread number:" <cthreadpool: m_vecbusythread.size () <Endl;
// Cout <"task to be run:" <tasklist-> size () <Endl;
Task-> Run ();
// Cout <"cthread: thread work" <Endl;
Cout <"TID:" <TID <"idle" <Endl;

}
Return (void *) 0;
}

Int cthreadpool: addtask (ctask * task)
{
This-> m_vectasklist.push_back (task );
Pthread_cond_signal (& m_pthreadcond );
Return 0;
}
Int cthreadpool: Create ()
{
For (INT I = 0; I <m_ithreadnum; I ++)
{
Pthread_t tid = 0;
Pthread_create (& tid, null, threadfunc, & m_vectasklist );
M_vecidlethread.push_back (TID );
}
Return 0;
}

Int cthreadpool: stopall ()
{
Vector <pthread_t>: iterator iter = m_vecidlethread.begin ();
While (ITER! = M_vecidlethread.end ())
{
Pthread_cancel (* ITER );
Pthread_join (* ITER, null );
ITER ++;
}

Iter = m_vecbusythread.begin ();
While (ITER! = M_vecbusythread.end ())
{
Pthread_cancel (* ITER );
Pthread_join (* ITER, null );
ITER ++;
}

Return 0;
}

Simple Example:

×××××××Test. cpp

# Include "cthread. H"
# Include <iostream>

Using namespace STD;

Class cworktask: Public ctask
{
Public:
Cworktask ()
{}
Int run ()
{
Cout <(char *) This-> m_ptrdata <Endl;
Sleep (10 );
Return 0;
}
};

Int main ()
{
Cworktask taskobj;
Char sztmp [] = "This is the first thread running, haha success ";
Taskobj. setdata (void *) sztmp );
Cthreadpool threadpool (10 );
For (INT I = 0; I <11; I ++)
{
Threadpool. addtask (& taskobj );
}
While (1)
{
Sleep (120 );
}
Return 0;
}

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.