CThreadPool.h
cpp
#pragma once
#include <pthread.h>
#include <list>
#include <queue>
#include <iostream>
#include <algorithm>
#include "CBaseTask.h"
#define MIN_THREAD_NUM 10
using namespace std;
class CThreadPool
{
public:
CThreadPool(const int num = MIN_THREAD_NUM);
~CThreadPool();
// 添加任务
void pushTask(CBaseTask* task);
// 取出任务
CBaseTask* popTask();
// 从忙碌链表中删除添加到空闲链表
void moveToIdle(pthread_t id);
// 从空闲链表中删除添加到忙碌链表
void moveToBusy(pthread_t id);
// 判断任务队列是否为空
bool queueIsEmpty();
// 操作互斥量
void lock();
void unlock();
//操作条件变量
void wait(); // 阻塞线程
void wakeup(); // 唤醒线程
static void* pthread_function(void* arg);
private:
int threadMinNum; // 线程数量最小值
int threadMaxNum; // 线程数量最大值
// 公共数据
queue<CBaseTask*>taskQueue; // 任务队列
list<pthread_t>idleList; // 空闲线程链表
list<pthread_t>busyList; // 忙碌线程链表
pthread_mutex_t mutex; // 互斥量
pthread_cond_t cond; // 线程条件变量 控制 阻塞/唤醒
};
CThreadPool.cpp
cpp
#include "CThreadPool.h"
CThreadPool::CThreadPool(const int num)
{
this->threadMinNum = num;
// 互斥量初始化
pthread_mutex_init(&(this->mutex), NULL);
// 条件变量初始化
pthread_cond_init(&(this->cond), NULL);
for (int i = 0; i < this->threadMinNum; i++)
{
pthread_t id;
pthread_create(&id, NULL, this->pthread_function, this);
// 将线程放入空闲列表
this->idleList.push_back(id);
}
}
CThreadPool::~CThreadPool()
{
}
void CThreadPool::pushTask(CBaseTask* task)
{
this->taskQueue.push(task);
this->wakeup();
}
CBaseTask* CThreadPool::popTask()
{
// 取出队列中的任务
CBaseTask* task = this->taskQueue.front();
// 删除队列中的任务
this->taskQueue.pop();
return task;
}
void CThreadPool::moveToIdle(pthread_t id)
{
list<pthread_t>::iterator itr;
itr = find(this->busyList.begin(), this->busyList.end(), id);
if (itr != this->busyList.end())
{
this->busyList.erase(itr);
this->idleList.push_back(*(itr));
}
}
void CThreadPool::moveToBusy(pthread_t id)
{
list<pthread_t>::iterator itr;
itr = find(this->idleList.begin(), this->idleList.end(), id);
if (itr != this->idleList.end())
{
this->idleList.erase(itr);
this->busyList.push_back(*(itr));
}
}
bool CThreadPool::queueIsEmpty()
{
return this->taskQueue.empty();
}
void CThreadPool::lock()
{
pthread_mutex_lock(&(this->mutex));
}
void CThreadPool::unlock()
{
pthread_mutex_unlock(&(this->mutex));
}
void CThreadPool::wait()
{
pthread_cond_wait(&(this->cond), &(this->mutex));
}
void CThreadPool::wakeup()
{
pthread_cond_signal(&(this->cond));
}
void* CThreadPool::pthread_function(void* arg)
{
// 线程执行函数中 获取运行线程本身自己的id号
pthread_t threadid = pthread_self();
/*
* 功能:确保主线程与当前执行的线程逻辑完全分离,当前线程执行结束,id会自动释放
* 目的:为了声明这个线程不会阻塞主线程,pthread_detach不会种植线程的运行
*/
pthread_detach(threadid);
CThreadPool* pool = (CThreadPool*)arg;
while (1)
{
pool->lock(); // 其余线程都无法执行lock
while (pool->queueIsEmpty())
{
pool->wait(); // 阻塞1个线程
}
cout << "线程工作前 任务数:" << pool->taskQueue.size() << endl;
cout << "线程工作前 忙碌线程数:" << pool->busyList.size() << endl;
cout << "线程工作前 空闲线程数:" << pool->idleList.size() << endl;
if (pool->busyList.size() == pool->threadMinNum && pool->busyList.size() + pool->idleList.size() < pool->threadMaxNum)
{
pthread_t id;
pthread_create(&id, NULL, pool->pthread_function, pool);
// 将线程放入空闲列表
pool->idleList.push_back(id);
}
pool->moveToBusy(threadid);
CBaseTask* task = pool->popTask();
pool->unlock();
// 任务开始工作
task->work();
pool->lock();
pool->moveToIdle(threadid);
pool->unlock();
cout << "线程工作后 任务数:" << pool->taskQueue.size() << endl;
cout << "线程工作后 忙碌线程数:" << pool->busyList.size() << endl;
cout << "线程工作后 空闲线程数:" << pool->idleList.size() << endl;
cout << "------------------------------------------------------" << endl;
}
return nullptr;
}
main.cpp
cpp
#include <iostream>
#include"CThreadPool.h"
#include "CBaseTask.h"
#include "CChildTask.h"
using namespace std;
int main()
{
CThreadPool* pool = new CThreadPool();
for (int i = 1; i <= 30; i++)
{
char buf[40] = { 0 };
sprintf(buf, "任务%d", i);
// 创建任务
CBaseTask* task = new CChildTask(buf);
// 添加任务进入线程池
pool->pushTask(task);
sleep(1);
}
while (1) {};
return 0;
}