线程池的实现

13 篇文章 0 订阅

为什么要使用线程池:因为线程的创建和销毁占了大量的CPU等系统资源,使用线程池可以解决这种情况,提高服务器的性能。

线程池的思想:(1)先在内存中开辟出一些数目固定的线程。(2)当请求到达时,从线程池中选择一个空闲的线程来服务,服务完成时,线程放入线程池。(3)当请求到答时,将请求放到任务队列中,等有空闲的线程时处理。

代码使用c++实现的:

1、使用互斥锁,来保证了线程安全。

2、使用信号量,来控制当没有请求到来时,线程处于等待。

3、创建线程时,线程的入口函数,需要声明为静态的,因为类的成员函数,不能作为线程创建的参数,因为pthread_create需要的参数类型为void*(*)(void*),而类的成员函数的类型为void*(threadpool::)(void*),参数类型不匹配。需要声明为静态的,那么类的成员函数就不带this指针,参数就匹配了。而且新线程要用到其他类的成员函数和成员变量,需要显示的把this指针传进去。

#include<iostream>
using namespace std;
#include<queue>
#include<pthread.h>
#include<semaphore.h>
#include<errno.h>
#include<cstdio>
class mutexlock
{
	public:
		mutexlock()
		{
			pthread_mutex_init(&mutex,NULL);
		}
		void lock()
		{
			pthread_mutex_lock(&mutex);
		}
		void unlock()
		{
			pthread_mutex_unlock(&mutex);
		}
		~mutexlock()
		{
			pthread_mutex_destroy(&mutex);
		}
	private:
		pthread_mutex_t mutex;
};

class Sem
{
	public:
	    Sem()
		{
			sem_init(&s,0,0);
		}
		void wait()
		{
			sem_wait(&s);
		}
		void post()
		{
			sem_post(&s);
		}
		~Sem()
		{
			sem_destroy(&s);
		}
	private:
		sem_t s;
};

template<class T>
class threadpool
{
	public:
		threadpool(int num1=10,int num2=1000)
			:threadnums(num1)
			,requestqueue(num2)
			,flag(false)
    	{
			threadbuf=new pthread_t[threadnums]; 
			//开辟threadnums大小的数组,存放线程id
			
			//创建线程
			for(int i=0;i<threadnums;i++)
			{
				if(pthread_create(threadbuf+i,NULL,start_routine,(void*)this))
		       //pthread_create要调用类的从成员函数,必须把函数声明为静态的
				{
					delete []threadbuf;
					perror("pthread_create");
				}
				if(pthread_detach(threadbuf[i])) //分离线程
				{
					delete []threadbuf;
					perror("pthread_detach");
				}
			}
		}
		bool workrequest(T* request) //把请求放到队列中
		{
			ml.lock(); //加锁,保证线程安全
			q.push(request);
                        ml.unlock();
			sem.post();
		}
		~threadpool()
		{
			delete []threadbuf;
			flag=true;
		}

	private:
                static void* start_routine(void* arg);   //线程开始运行的函数
		void run()
		{
			//所有的线程执行到这一步了
			while(!flag) //一个线程执行完后,他会继续排队再次执行,而不是直接销毁了
			{
				sem.wait();
				ml.lock(); //只有一个线程获得了锁
				while(q.empty())
				{
					ml.unlock();
					continue;
				}
				T* front=q.front(); //得到请求任务
				q.pop();
				ml.unlock();
				front->protmethod(); //线程就去执行这个请求任务
			}	
		}
		int threadnums; //线程的数目
		int requestqueue; //请求队列的大小
		pthread_t* threadbuf; //用来r存放线程id
		queue<T*> q;  //请求队列
		mutexlock ml; //互斥锁
	        Sem sem; //信号量
		bool flag; //判断主进程有没有退出
};	
template<class T>
void* threadpool<T>::start_routine(void* arg)   //线程开始运行的函数
{
	threadpool* p=(threadpool*)arg;  //必须要传的
	p->run();
	return p;
}
int main()
{
	threadpool<int> pool;
	return 0;
}




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值