POSIX线程(三)linux下c++线程池代码示例

线程池理论部分可参考其他文章:
linux线程池的实现——bobo

基础的线程池demo

本文仅放上一个基础的线程池demo:
分为三个文件:
main.cpp
PthreadPool.cpp
PthreadPool.h
后两个文件写线程池相关应用接口

main.cpp

#include <iostream>
#include <pthread.h>//pthread_create
#include <stdio.h>//perror
#include <unistd.h>//sleep
#include <semaphore.h>
#include "PthreadPool.h"
using namespace std;


void teskone()
{
	cout << "tesk1" << endl;
	//每个线程执行的时候真正的业务代码写在这里

}
void tesktwo()
{
	cout << "tesk2" << endl;

}
void teskthree()
{
	cout << "tesk3" << endl;
}


int main(int argc, char *argv[])
{
	PThreadPool *pool = new PThreadPool(4);//线程创建的合理数值应该是CPU核心数量的2倍
	pool->Start();
	//pool->addTask(teskone);//若函数传参,不是在面传参而是去调用传参
	//pool->addTask(tesktwo);
	
	
	//假如一个线程业务代码需要执行10s
	//我们线程池最大数量假设只有3个,如果不断往里面添加任务,达到最大线程数
	//存在阻塞排队等待可能,所以要对addtask返回值做判断
	while (1)
	{

		if ((pool->addTask(teskone)) < 0)	//存在线程池满可能,所以要对addtask返回值做判断
		{
			cout << "thread poll full ,please wait" << endl;
		}
		if ((pool->addTask(tesktwo)) < 0)	//存在线程池满可能,所以要对addtask返回值做判断
		{
			cout << "thread poll full ,please wait" << endl;
		}
		if ((pool->addTask(teskthree)) < 0)	//存在线程池满可能,所以要对addtask返回值做判断
		{
			cout << "thread poll full ,please wait" << endl;
		}	
		sleep(1);
	}
	return 0;
}


PthreadPool.h


#include <stdio.h>//perror
#include <iostream>
#include <pthread.h>//线程
#include <vector>
#include <unistd.h>//sleep
#include <semaphore.h>//互斥量
using namespace std;

typedef struct
{
	pthread_t pthread_id;
}THREAD_INFO;

//定义了一个函数指针,这个函数没有返回值没有参数
typedef void(*Task)(void);//定义一个指针类型的数据


//线程池
class PThreadPool
{
public:
	PThreadPool(int pthread_max_count);//线程的虽大数量
	void Start();//启动线程池
	//静态是独立于类的,与this无关
	static void *thread_handle(void*data);//线程执行函数,静态方法,因为pthread_create的第三个参数void*(*)
	
	bool m_isQuit;//线程是否退出标志	
	pthread_mutex_t m_mutex;//互斥量变量
	pthread_cond_t m_cond;//条件变量类型
	
	vector<Task> taskVector;//保存任务函数向量
	
	int addTask(Task t);
	
	int activeThread;//活跃(正在运行的)线程数量
private:
	pthread_mutex_t activeThread_mutex;//活跃线程数量的互斥量
	
	vector < THREAD_INFO> threadInfo_vector;//保存线程信息的向量
	//m开头表示类的私有成员member

	int m_thread_max;//线程池是最大线程数量
	int m_current_threads;//当前启动的线程数量
	
};

PthreadPool.cpp

#include "PthreadPool.h"
#include <stdio.h>//perror
#include <iostream>
#include <pthread.h>//线程
#include <vector>
#include <unistd.h>//sleep
#include <semaphore.h>//互斥量
#include <string.h>//memset

PThreadPool::PThreadPool(int pthread_max_count)
{
	m_isQuit = false;
	this->activeThread = 0;
	m_thread_max = pthread_max_count;//线程池是最大线程数量
	m_current_threads=0;//当前启动的线程数量
	//对互斥量进行初始化
	pthread_mutex_init(&m_mutex, NULL);
	//条件变量初始化
	pthread_cond_init(&m_cond, NULL);

}
void* PThreadPool::thread_handle(void*data)//所以的线程都会执行同一个静态方法
{
	//这个是静态方法,问题在于静态方法里面不能访问this成员,所以用到了线程的第四个参数
	PThreadPool *pool = (PThreadPool*)data;//传参再转换类型
	

	
	while (!pool->m_isQuit)
	{
		pthread_mutex_lock(&pool->m_mutex);
		pthread_cond_wait(&pool->m_cond, &pool->m_mutex);//条件变量等待在这边,直到addTask发信号才往下执行
		cout << "wake up" << endl;
			pthread_mutex_lock(&pool->activeThread_mutex); //activeThread这个变量会被很多线程同时访问,所以需要使用互斥量进行保护
			pool->activeThread++;//活跃(正在运行的)线程数量+1
			pthread_mutex_unlock(&pool->activeThread_mutex); 
		
		//下面写业务
		//从taskVector中取第一个业务,取出来执行向量里面的函数指针,执行完就把它从列表中删除
		Task t = pool->taskVector[0];
		t();//这样就会执行取出来的函数
		pool->taskVector.erase(pool->taskVector.begin());//删除执行完的第一个,后面的会自动补上来
		pthread_mutex_unlock(&pool->m_mutex);		
		
			pthread_mutex_lock(&pool->activeThread_mutex); //activeThread这个变量会被很多线程同时访问,所以需要使用互斥量进行保护
			pool->activeThread--;//活跃(正在运行的)线程数量-1
			pthread_mutex_unlock(&pool->activeThread_mutex); 
	}
}


void PThreadPool::Start()//启动线程池
{
	
	//这里的start是根据构造函数传递进来的线程中要创建的线程数量来创建线程
	for (int i = 0; i < m_thread_max; i++)
	{
		pthread_t pthread_id;
			//在pthread_ create 的第四个参数传 this  在线程处理函数里创建对象也能用类的属性

		if (pthread_create(&pthread_id, NULL, PThreadPool::thread_handle, (void*)this) < 0)//2指定线程属性3函数指针4给线程传递的参数:类指针
		{
			perror("pthread create err:");
		}
		THREAD_INFO info;
		memset(&info, 0, sizeof(THREAD_INFO));
		this->threadInfo_vector.push_back(info);
	}
}

int PThreadPool::addTask(Task t)
{

	//cout << "activeThread " << this->activeThread+1 << endl;
	//cout << "m_thread_max" << m_thread_max << endl;
	if (this->activeThread == m_thread_max)//所有线程都在运行就不能再加了
	{
		return -1;
	}
	else if (this->activeThread < m_thread_max)
	{
		taskVector.push_back(t);//添加任务,一个函数就是一个任务
		//这里唤醒刚才因为条件变量睡眠的线程
		pthread_mutex_lock(&m_mutex);
		pthread_cond_signal(&m_cond);//一旦被添加进来,就会通知线程唤醒
		pthread_mutex_unlock(&m_mutex);
	}
}

打印结果:每1秒运行3个任务一次(若m_thread_max小于同时任务数则会拒绝运行,直到下一次循环才运行,本例因为任务只是打印所以不会出现等待提示)
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值