#ifndef __TASK_QUEUE_H__
#define __TASK_QUEUE_H__
#include <queue>
#include <pthread.h>
using callback = void (*)(void *arg);
// 任务结构体
template <typename T>
struct Task
{
Task() {
function = nullptr;
arg = nullptr;
}
Task(callback f, void *arg) {
this->arg = (T*)arg;
function = f;
}
callback function;
T *arg;
};
template <typename T>
class TaskQueue
{
public:
TaskQueue();
~TaskQueue();
// 添加任务
void addTask(Task<T> task);
void addTask(callback f, void *arg);
// 取出一个任务
Task<T> takeTask();
// 获取当前任务的个数
inline size_t taskNumber() {
return m_taskQ.size();
}
private:
pthread_mutex_t m_mutex;
std::queue<Task<T>> m_taskQ;
};
#endif
#include "TaskQueue.h"
template <typename T>
TaskQueue<T>::TaskQueue()
{
pthread_mutex_init(&m_mutex, NULL);
}
template <typename T>
TaskQueue<T>::~TaskQueue()
{
pthread_mutex_destroy(&m_mutex);
}
// 添加任务
template <typename T>
void TaskQueue<T>::addTask(Task<T> task)
{
pthread_mutex_lock(&m_mutex);
m_taskQ.push(task);
pthread_mutex_unlock(&m_mutex);
}
template <typename T>
void TaskQueue<T>::addTask(callback f, void *arg)
{
pthread_mutex_lock(&m_mutex);
m_taskQ.push(Task<T>(f, arg));
pthread_mutex_unlock(&m_mutex);
}
// 取出一个任务
template <typename T>
Task<T> TaskQueue<T>::takeTask()
{
Task<T> t;
pthread_mutex_lock(&m_mutex);
if (!m_taskQ.empty()) {
t = m_taskQ.front();
m_taskQ.pop();
}
pthread_mutex_unlock(&m_mutex);
return t;
}
#ifndef __THREAD_POOL_H__
#define __THREAD_POOL_H__
#include "TaskQueue.h"
#include "TaskQueue.cc"
template <typename T>
class ThreadPool
{
public:
// 创建线程池
ThreadPool(int min, int max);
// 销毁线程池
~ThreadPool();
// 给线程池添加任务
void addTask(Task<T> task);
// 获取线程池中的工作线程个数
int getBusyNum();
// 获取存活线程个数
int getAliveNum();
private:
// 工作的线程(消费者线程)任务函数
static void *worker(void *arg);
// 管理者线程任务函数
static void *manager(void *arg);
// 单个线程退出
void threadExit();
private:
// 任务队列
TaskQueue<T> *taskQ;
pthread_t managerID; // 管理者线程ID
pthread_t *threadIDs; // 工作者的线程ID
int minNum; // 最小线程数
int maxNum; // 最大线程数
int busyNum; // 忙的线程个数
int liveNum; // 存活的线程个数
int exitNum; // 要销毁的线程个数
pthread_mutex_t mutexPool; // 锁整个线程池
pthread_cond_t notEmpty; // 任务队列为空
bool shutdown; // 是不是销毁线程池,销毁为1,不销毁为0
static const int NUMBER = 2;
};
#endif
#include <iostream>
#include <string.h>
#include <string>
#include <unistd.h>
#include "Threadpool.h"
using namespace std;
// 创建线程池
template <typename T>
ThreadPool<T>::ThreadPool(int min, int max)
{
// 实例化任务对象
do {
taskQ = new TaskQueue<T>;
if (taskQ == nullptr) {
cout << "malloc taskQ fail..." << endl;
break;
}
threadIDs = new pthread_t[max];
if (threadIDs == nullptr) {
cout << "malloc threadIDs fail..." << endl;
break;
}
memset(threadIDs, 0, sizeof(pthread_t) * max);
minNum = min;
maxNum = max;
busyNum = 0;
liveNum = min;
exitNum = 0;
if (pthread_mutex_init(&mutexPool, NULL) != 0 ||
pthread_cond_init(¬Empty, NULL)) {
cout << "mutex of condition init fail...\n";
}
shutdown = false;
// 创建线程
pthread_create(&managerID, NULL, manager, this);
for (int i = 0; i < min; ++i) {
pthread_create(&threadIDs[i], NULL, worker, this);
}
return;
} while (0);
// 构造函数执行失败后需要释放资源
if (threadIDs) delete []threadIDs;
if (taskQ) delete taskQ;
}
// 销毁线程池
template <typename T>
ThreadPool<T>::~ThreadPool()
{
// 关闭线程池
shutdown = true;
// 阻塞回收管理者线程
pthread_join(managerID, NULL);
// 唤醒阻塞的消费者线程
for (int i = 0; i < liveNum; ++i) {
pthread_cond_signal(¬Empty);
}
// 释放堆内存
if (taskQ) {
delete taskQ;
}
if (threadIDs) {
delete []threadIDs;
}
pthread_mutex_destroy(&mutexPool);
pthread_cond_destroy(¬Empty);
}
// 给线程池添加任务
template <typename T>
void ThreadPool<T>::addTask(Task<T> task)
{
if (shutdown) {
return;
}
// 添加任务
taskQ->addTask(task);
pthread_cond_signal(¬Empty);
}
// 获取线程池中的工作线程个数
template <typename T>
int ThreadPool<T>::getBusyNum()
{
pthread_mutex_lock(&mutexPool);
int busyNum = this->busyNum;
pthread_mutex_unlock(&mutexPool);
return busyNum;
}
// 获取存活线程个数
template <typename T>
int ThreadPool<T>::getAliveNum()
{
pthread_mutex_lock(&mutexPool);
int liveNum = this->liveNum;
pthread_mutex_unlock(&mutexPool);
return liveNum;
}
// 工作的线程(消费者线程)任务函数
template <typename T>
void *ThreadPool<T>::worker(void *arg)
{
ThreadPool *pool = static_cast<ThreadPool *>(arg);
while (true)
{
pthread_mutex_lock(&pool->mutexPool);
// 当前任务队列是否为空
while (pool->taskQ->taskNumber() == 0 && !pool->shutdown)
{
// 阻塞工作线程
pthread_cond_wait(&pool->notEmpty, &pool->mutexPool);
// 判断是不是要销毁的线程
if (pool->exitNum > 0) {
pool->exitNum--;
if (pool->liveNum > pool->minNum) {
pool->liveNum--;
pthread_mutex_unlock(&pool->mutexPool);
pool->threadExit();
}
}
}
// 判断线程是否被关闭了
if (pool->shutdown) {
pthread_mutex_unlock(&pool->mutexPool);
pool->threadExit();
}
// 从任务队列中取出一个任务
Task<T> task = pool->taskQ->takeTask();
//
pool->busyNum++;
pthread_mutex_unlock(&pool->mutexPool);
cout << "thread = " << to_string(pthread_self()) << " start working...\n";
task.function(task.arg);
delete task.arg;
task.arg = nullptr;
cout << "thread = " << to_string(pthread_self()) << " end working...\n";
pthread_mutex_lock(&pool->mutexPool);
pool->busyNum--;
pthread_mutex_unlock(&pool->mutexPool);
}
return NULL;
}
// 管理者线程任务函数
template <typename T>
void *ThreadPool<T>::manager(void *arg)
{
ThreadPool *pool = static_cast<ThreadPool *>(arg);
while (!pool->shutdown) {
// 每隔3s检查一次
sleep(3);
// 取出线程池中任务的数量和当前线程的数量
pthread_mutex_lock(&pool->mutexPool);
int queueSize = pool->taskQ->taskNumber();
int liveNum = pool->liveNum;
int busyNum = pool->busyNum;
pthread_mutex_unlock(&pool->mutexPool);
// 创建线程
if (queueSize > liveNum && liveNum < pool->maxNum) {
pthread_mutex_lock(&pool->mutexPool);
int counter = 0;
for (int i = 0; i < pool->maxNum && counter < NUMBER && pool->liveNum; ++i) {
if (pool->threadIDs[i] == 0) {
pthread_create(&pool->threadIDs[i], NULL, worker, pool);
counter++;
pool->liveNum++;
}
}
pthread_mutex_unlock(&pool->mutexPool);
}
// 销毁线程
if (busyNum * 2 < liveNum && liveNum > pool->minNum) {
pthread_mutex_lock(&pool->mutexPool);
pool->exitNum = NUMBER;
pthread_mutex_unlock(&pool->mutexPool);
// 让工作的线程自杀
for (int i = 0; i < NUMBER; ++i) {
pthread_cond_signal(&pool->notEmpty);
}
}
}
return NULL;
}
// 单个线程退出
template <typename T>
void ThreadPool<T>::threadExit()
{
pthread_t tid = pthread_self();
for (int i = 0; i < maxNum; ++i) {
if (threadIDs[i] == tid) {
threadIDs[i] = 0;
cout << "threadExit() callled, " << to_string(tid) << "exiting...\n";
break;
}
}
pthread_exit(NULL);
}
#include <iostream>
#include <unistd.h>
#include "Threadpool.h"
// #include "TaskQueue.h"
#include "Threadpool.cc"
using namespace std;
void taskTestFunc(void *arg)
{
int num = *(int *)arg;
cout << " thread " << pthread_self() << "is working, number = " << num << endl;
sleep(1);
}
int main()
{
// 创建线程池对象
ThreadPool<int> pool(3, 10);
for (int i = 0; i < 100; ++i) {
int *num = new int(i + 100);
pool.addTask(Task<int>(taskTestFunc, num));
}
sleep(20);
return 0;
}
$ g++ test.cc Threadpool.cc TaskQueue.cc -o test -pthread