1.线程池用来干嘛
用户有任务需要执行,向任务队列中加入任务,线程池不断尝试从任务队列取出任务,执行任务。
2.代码
#ifndef PTHREAD_POOL_H
#define PTHREAD_POOL_H
#include <queue>
#include <pthread.h>
//线程池类
class pthreadPool
{
private:
//任务
struct user_data
{
void *(*func)(void *);
void *arg;
};
//每个线程有一个work
struct work
{
pthread_t pthread_id;
bool is_working;
user_data *user;
pthreadPool *pool;
};
public:
//仅向用户提供的方法
pthreadPool(int max_pthread, int max_work);
~pthreadPool();
bool add_work(void *(*func)(void *), void *arg, int len);
private:
bool m_add_work(user_data *user);
//线程运行函数不能有隐含this指针参数
static void *m_run(void *arg);
void pthread_loop(work *my_work);
private:
int m_max_thread;
int m_free_thread;
int m_max_work;
work *m_works;
pthread_cond_t m_cond;
pthread_mutex_t m_lock;
//任务队列
std::queue<user_data *> m_queue;
bool m_stop;
};
#endif
#include <iostream>
#include <string.h>
#include <pthread.h>
#include <unistd.h>
#include "pthreadPool.h"
using namespace std;
//线程创建、分离属性、初始化成员变量
pthreadPool::pthreadPool(int max_pthread, int max_work): m_max_thread(max_pthread), m_max_work(max_work), m_free_thread(max_pthread)
{
if( max_pthread <= 0 || max_work <= 0 )
{
return;
}
//初始化锁、条件变量、成员变量
if(pthread_mutex_init(&m_lock, NULL))
{
perror("mutex_init");
}
if(pthread_cond_init(&m_cond, 0))
{
perror("cond_init");
}
m_stop = false;
//创建工作队列
m_works = new(std::nothrow) work[m_max_work];
if(m_works == NULL)
{
perror("new work");
return;
}
//创建线程、分离属性
for(int i = 0; i < m_max_thread; i++)
{
if(pthread_create(&m_works[i].pthread_id, NULL, m_run, (void *)&m_works[i]))
{
perror("pthread_create");
}
m_works[i].pool = this;
m_works[i].is_working = false;
pthread_detach(m_works[i].pthread_id);
}
}
//设置停止线程参数,唤醒线程,释放空间
pthreadPool::~pthreadPool()
{
m_stop = true;
//TODO:线程强制退出?
pthread_cond_broadcast(&m_cond);
delete[]m_works;
}
//创建user_data,调用内部add,len要非0
bool pthreadPool::add_work(void *(*func)(void *), void *arg, int len)
{
user_data *my_user_data = new(std::nothrow) user_data;
if(my_user_data == NULL)
{
return false;
}
my_user_data->func = func;
my_user_data->arg = malloc(len);
if(my_user_data == NULL)
{
delete my_user_data;
return false;
}
memcpy(my_user_data->arg, arg, len);
if(!m_add_work(my_user_data))
{
free(my_user_data->arg);
delete my_user_data;
return false;
}
return true;
}
bool pthreadPool::m_add_work(user_data *user)
{
if(m_queue.size() >= m_max_work)
{
return false;
}
m_queue.push(user);
return true;
}
//静态线程运行函数
void *pthreadPool::m_run(void *arg)
{
//sleep(20);
work *my_work = (work *)arg;
my_work->pool->pthread_loop(my_work);
}
//循环等待任务队列,处理任务
void pthreadPool::pthread_loop(work *my_work)
{
while(1)
{
pthread_mutex_lock(&m_lock);
while(m_queue.empty())
{
if(m_stop)
{
break;
}
pthread_cond_wait(&m_cond, &m_lock);
}
if(m_stop)
{
pthread_mutex_unlock(&m_lock);
break;
}
//从任务队列取出任务,更新数据,解锁,执行
struct user_data * my_user_data = m_queue.front();
m_queue.pop();
m_free_thread--;
pthread_mutex_unlock(&m_lock);
my_work->is_working = true;
my_user_data->func(my_user_data->arg);
my_work->is_working = false;
pthread_mutex_lock(&m_lock);
m_free_thread++;
pthread_mutex_unlock(&m_lock);
//任务执行完毕,释放资源
free(my_user_data->arg);
delete my_user_data;
}
//线程结束,资源在虚构中释放
}
3.测试代码
#include <iostream>
#include <unistd.h>
#include "pthreadPool.h"
using namespace std;
void* hello(void *arg)
{
int *day = (int *)arg;
std::cout << "today is " << *day << std::endl;
return NULL;
}
int day = 10;
int main()
{
pthreadPool pool(8, 20);
for(int i = 0; i < 10; i++)
{
if( !pool.add_work(hello, (void *)&day, sizeof(i)) )
{
cout << "添加失败" << endl;
}
}
sleep(10);
// hello(&day);
return 0;
}