简易线程池的实现
1 线程池
为了避免多线程操作过程种线程频繁申请和释放所带来的性能消耗,可以提前创建多个线程,当有任务到来时从线程池中选择一个线程执行,执行完后继续在线程池中待命。
核心是使用一个工作队列,主线程往工作队列中添加工作,工作线程从队列中取出工作并执行。
对工作队列的操作就是经典的生产者—消费者模型,需要用到互斥锁和条件变量。
2 工作定义
通过函数指针指向执行函数。
typedef struct Task{
void (*func)(void* arg);
void* arg;
}Task;
3 线程池定义
使用 list 容器来存储工作,定义工作队列的最大数 m_max_requests 和 线程总数 m_max_threads。在对工作队列操作时需要用到互斥锁 m_mutex_pool,条件变量 m_notfull 和 m_notempty。
class ThreadPool{
public:
ThreadPool(int m_max_threads, int m_max_requests);
~ThreadPool();
bool addWork(void(*func)(void*), void* arg);
private:
static void* worker(void* arg);
void run();
private:
std::list<Task*> m_workqueue; /*工作队列*/
int m_max_requests; /*请求队列中允许的最大请求数*/
int m_max_threads; /*线程总数*/
pthread_t* m_worker_threads; /*工作线程*/
pthread_mutex_t m_mutex_pool;
pthread_cond_t m_notfull;
pthread_cond_t m_notempty;
bool m_stop;
};
ThreadPool::ThreadPool(int m_max_threads, int m_max_requests):
m_max_threads(m_max_threads), m_max_requests(m_max_requests), m_stop(false){
if(m_max_threads <= 0 || m_max_requests <= 0){
throw std::exception();
}
/*创建线程池*/
m_worker_threads = new pthread_t[m_max_threads];
if(!m_worker_threads){
throw std::exception();
}
//memset(m_worker_threads, 0, sizeof(m_worker_threads));
/*初始化互斥锁、条件变量*/
if(0 != pthread_mutex_init(&m_mutex_pool, NULL) ||
0 != pthread_cond_init(&m_notfull, NULL) ||
0 != pthread_cond_init(&m_notempty, NULL)){
throw std::exception();
}
/*创建工作线程*/
for(int i=0; i<m_max_threads; ++i){
printf("Create the %dth thread\n", i);
if(0 != pthread_create(&m_worker_threads[i], 0, worker, this)){
delete []m_worker_threads;
throw std::exception();
};
if(pthread_detach(m_worker_threads[i])){
delete [] m_worker_threads;
throw std::exception();
}
}
}
ThreadPool::~ThreadPool(){
delete []m_worker_threads;
m_stop = true;
}
bool ThreadPool::addWork(void(*func)(void*), void* arg){
pthread_mutex_lock(&m_mutex_pool);
while(!m_stop && m_workqueue.size() >= m_max_requests){
pthread_cond_wait(&m_notfull, &m_mutex_pool);
}
if(m_stop){
pthread_mutex_unlock(&m_mutex_pool);
return false;
}
/*添加工作*/
Task* task = new Task;
task->func = func;
task->arg = arg;
m_workqueue.push_back(task);
pthread_mutex_unlock(&m_mutex_pool);
pthread_cond_signal(&m_notempty);
return true;
}
void* ThreadPool::worker(void* arg){
ThreadPool* pool = (ThreadPool*)arg;
pool->run();
return pool;
}
void ThreadPool::run(){
while(1){
pthread_mutex_lock(&m_mutex_pool);
while(m_workqueue.empty() && !m_stop){
pthread_cond_wait(&m_notempty, &m_mutex_pool);
}
/*从工作队列中取任务*/
Task* task = m_workqueue.front();
m_workqueue.pop_front();
pthread_mutex_unlock(&m_mutex_pool);
pthread_cond_signal(&m_notfull);
printf("Thread %ld start working...\n", pthread_self());
/*执行任务*/
task->func(task->arg);
delete task;
printf("Thread %ld end working...\n", pthread_self());
}
}
#endif
4 测试代码
#include "threadpool.h"
#include<iostream>
#include<unistd.h>
using namespace std;
void taskFunc(void* arg)
{
int num = *(int*)arg;
printf("Thread %ld is working, number = %d\n", pthread_self(), num);
sleep(1);
}
int main(){
ThreadPool* pool = new ThreadPool(10, 20);
for (int i = 0; i < 100; ++i)
{
int* num = (int*)malloc(sizeof(int));
*num = i;
pool->addWork(taskFunc, num);
}
sleep(30);
return 0;
}

References:
- 手写线程池 - C 语言版
- 《Linux高性能服务器编程》

浙公网安备 33010602011771号