线程池封装

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;
}
相关推荐
Two_brushes.4 分钟前
高性能分布式消息队列系统(二)
c++·后端·mq
异常君9 分钟前
TCP TIME_WAIT 状态:原理、问题与优化方案
java·linux·tcp/ip
秦少游在淮海24 分钟前
C++ - STL #什么是STL #STL的版本 #闭源开源 #STL的六大组件
开发语言·c++
夜月yeyue26 分钟前
高性能MCU的MPU与Cache优化详解
linux·开发语言·stm32·单片机·嵌入式硬件
@蓝莓果粒茶43 分钟前
LeetCode第245题_最短单词距离III
c语言·c++·笔记·学习·算法·leetcode·c#
平平无奇。。。1 小时前
Mysql库的操作和表的操作
linux·数据库·mysql
一张假钞1 小时前
Linux 下 ChromeDriver 安装
linux·运维·服务器
shark-chili1 小时前
Java并发编程哲学系列汇总
linux·运维·服务器·操作系统
showmeyourcode0.o2 小时前
QT常用控件(1)
开发语言·c++·qt
qq_243050792 小时前
rtpmixsound:实现音频混音攻击!全参数详细教程!Kali Linux教程!
linux·web安全·网络安全·黑客·渗透测试·voip·kali linux