This article describes the C + + thread pooling implementation method. Share to everyone for your reference. The specific analysis is as follows:
This thread pool is what I used to do in my work, the principle is to create a task queue, so that multiple threads mutually exclusive in the queue to pull out the task, and then execute, obviously, the queue is to be locked
Environment: Ubuntu Linux
FileName: locker.h
#ifndef locker_h_
#define Locker_h_
#include "pthread.h"
class LOCKER
{public
:
LOCKER ();
Virtual ~locker ();
bool Lock ();
void unlock ();
Private:
pthread_mutex_t M_mutex;
#endif/* Locker_h_ * *
FileName: locker.cpp
#include "Locker.h"
locker::locker ()
{
pthread_mutex_init (&m_mutex, 0);
}
Locker::~locker ()
{
Pthread_mutex_destroy (&m_mutex);
}
BOOL Locker::lock ()
{
if (0 = Pthread_mutex_lock (&m_mutex)) return
true;
return false;
}
void Locker::unlock ()
{
pthread_mutex_unlock (&m_mutex);
}
FileName: task_list.h
#ifndef task_list_h_
#define Task_list_h_
#include "LIST"
#include "locker.h"
#include "netinet/ In.h "
#include" semaphore.h "
using namespace std;
typedef void* (*thread_func) (void*);
The task running in the thread pool, for the downlink task, sin contains the destination address information
//Parm0 point to the object that emitted the data, parm1 to the data, parm2 to the length of the data
typedef struct
{
Thread_func FUNC;
void* parm0;
void* Parm1;
void* parm2;
} Task_info;
typedef list<task_info*> Task_list;
typedef list<task_info*>::iterator Ptask_list;
Class Task_list
{public
:
task_list ();
Virtual ~task_list ();
void Append_task (task_info* tsk);
task_info* Fetch_task ();
Private:
task_list m_tasklist;
Locker M_lk;
sem_t M_sem;
};
#endif/* Task_list_h_ * *
FileName: task_list.cpp
#include "task_list.h"
task_list::task_list ()
{
//Init semaphore
sem_init (&m_sem, 0, 0);
M_tasklist.clear ();
}
Task_list::~task_list ()
{while
(!m_tasklist.empty ())
{
task_info* tr = M_tasklist.front ();
M_tasklist.pop_front ();
if (tr)
delete tr;
}
Destroy Semaphore
Sem_destroy (&M_SEM);
}
void Task_list::append_task (task_info* tsk)
{
//Lock before Modify the list
m_lk.lock ();
M_tasklist.push_back (tsk);
M_lk.unlock ();
Increase the semaphore
Sem_post (&M_SEM);
}
task_info* Task_list::fetch_task ()
{
task_info* tr = NULL;
Sem_wait (&m_sem);
M_lk.lock ();
TR = M_tasklist.front ();
M_tasklist.pop_front ();
M_lk.unlock ();
return tr;
}
FileName: thread_pool.h
#ifndef thread_pool_h_
#define Thread_pool_h_
#include "task_list.h"
#include "pthread.h"
#define Default_thread_count 4
#define MAXIMUM_THREAD_COUNT 1000
class Thread_pool
{public
:
Thread_pool ();
Virtual ~thread_pool ();
int create_threads (int n = default_thread_count);
void Delete_threads ();
void Set_tasklist (task_list* plist);
void Del_tasklist ();
Protected:
static void* Thread_func (void* parm);
task_info* Get_task ();
Private:
int m_thread_cnt;
pthread_t M_pids[maximum_thread_count];
task_list* m_tasklist;
};
#endif/* Thread_pool_h_ * *
FileName: thread_pool.cpp
#include "thread_pool.h" Thread_pool::thread_pool () {m_thread_cnt = 0;
M_tasklist = NULL;
} thread_pool::~thread_pool () {delete_threads ();
} task_info* Thread_pool::get_task () {task_info* tr;
if (m_tasklist) {tr = M_tasklist->fetch_task ();
return TR;
return NULL;
} void* Thread_pool::thread_func (void* parm) {Thread_pool *PTP = static_cast<thread_pool*> (parm);
Task_info *task;
while (true) {task = Ptp->get_task ();
if (Task) {(*TASK->FUNC) (Task); Delete task;
Func is responsible for releasing Task_info}} return NULL;
int thread_pool::create_threads (int n) {if (n > Maximum_thread_count) n = maximum_thread_count;
Delete_threads ();
for (int i = 0; i < n; i++) {INT. ret = Pthread_create (&m_pids[i], NULL, Thread_func, (void*) this);
if (ret!= 0) break;
m_thread_cnt++;
return m_thread_cnt;
} void Thread_pool::d elete_threads (){for (int i = 0; i < m_thread_cnt i++) {void* retval;
Pthread_cancel (M_pids[i]);
Pthread_join (M_pids[i], &retval);
} m_thread_cnt = 0;
} void Thread_pool::set_tasklist (task_list* plist) {m_tasklist = plist;
} void Thread_pool::d el_tasklist () {m_tasklist = NULL;
}
FileName: test.cpp
#include "unistd.h"
#include "stdio.h"
#include "stdlib.h"
#include "task_list.h"
#include "thread_ Pool.h "
void* fun (void *parm)
{
task_info* ptk = (task_info*) parm;
pid_t tid = pthread_self ();
int count = (int) ptk->parm0;
printf ("count=%d, tid=%d\n", Count, Tid);
return NULL;
}
int main ()
{
int count = 0;
Thread_pool TP;
Task_list tl;
Tp.create_threads (4-1);
Tp.set_tasklist (&TL);
while (1)
{
task_info* PTI = NULL;
PTI = (Task_info *) malloc (sizeof (Task_info));
Pti->func = fun;
PTI->PARM0 = (void *) count;
Tl.append_task (PTI);
count++;
Sleep (2);
}
printf ("hello,world\n");
return 0;
}
Compile run, I was built with Ecplise Automake project, so as long as the modification of makefile.am can be compiled successfully
FileName: makefile.am
Bin_programs=test
test_sources=test.cpp locker.h locker.cpp \ task_list.h
task_list.cpp \
thread_pool.h Thread_pool.cpp
Test_ldadd=-lpthread
Execution results:
Count=0, tid=-1219888272
count=1, tid=-1219888272 count=2, tid=-1228280976 count=3
, tid=-1236673680
count=4, tid=-1219888272
count=5, tid=-1228280976 count=6, tid=-1236673680 count=7
, tid=- 1219888272
count=8, tid=-1228280976
count=9, tid=-1236673680
I hope this article will help you with the C + + program design.