线程池封装

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;
}
相关推荐
纪元A梦3 小时前
华为OD机试真题——荒岛求生(2025A卷:200分)Java/python/JavaScript/C/C++/GO最佳实现
java·c语言·javascript·c++·python·华为od·go
爱吃涮毛肚的肥肥(暂时吃不了版)4 小时前
仿腾讯会议——创建房间&加入房间
c++·qt·面试·职场和发展·腾讯会议
帅得不敢出门5 小时前
Ubuntu打开中文文本乱码
linux·运维·ubuntu·vim
pp-周子晗(努力赶上课程进度版)5 小时前
【计算机网络-传输层】传输层协议-UDP
linux·计算机网络·udp
only火车头5 小时前
mdadm 报错: buffer overflow detected
linux·mdadm·blktest
Flaming_1235 小时前
将develop分支的修改同步到main分支
linux·git·merge
weixin_428498496 小时前
使用 pgrep 杀掉所有指定进程
linux
rayylee6 小时前
Ubuntu也开始锈化了?Ubuntu 计划在 25.10 版本开始引入 Rust Coreutils
linux·ubuntu·rust
gxh19926 小时前
springboot微服务连接nacos超时
linux·后端·微服务·nacos
@电子爱好者6 小时前
Vscode+git笔记
linux·职场和发展