【linux线程(壹)】——初识线程(区分线程和进程,线程创建的基本操作)
【线程(二)】——互斥量的详细解析
【线程(三)】———条件变量的详细解析
什么是线程池?
线程池是一种线程使用模式,它是将一定数量线程和缓冲队列预存在一个池子中,池子中的线程轮流的往任务队列中拿去任务并完成任务,而任务队列往外开发一个接口,使其他线程能够往任务队列中推送任务。
线程池的优点:
线程池能够减少线程的创建和销毁所消耗的时间和系统资源的开销,如果不使用线程池,将可能造成系统创建大量的同类线程而导致消耗完内存或“过度切换”的问题。
线程池的应用场景
1,需要大量线程来完成任务,且完成任务的时间较短,WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适的。因为单个任务小,而任务数量巨大,但对于长时间的任务,比如一个Telnet连接请求,线程池的优点不明显,因为Telnet会话时间比线程的创建时间太多了。
2.对性能苛刻要求的的应用,比如服务器迅速响应客户请求。
3.接受突发的大量请求时,但不至于使服务器创建大量的线程,在没有线程池情况下,将产生大量的线程,短时间内会产生大量的线程可能使内存达到极限,出现错误。
线程池的实现
线程池的成员变量:
- 任务队列,quueu<T> q;
- 线程个数,int num;
- 互斥量,pthread_mutex_t lock;
- 条件变量,pthread_cond_t cond;
创建线程池,需要创建一个任务队列和一定数量的线程。由于每次只能有一个线程进入队列中放任务和拿任务,所以此时需要定义一个互斥量进行维护,如果任务队列中的没有任务,此时线程就不能进入任务队列中,所以就创建一个条件变量。
线程池的代码(C++)
** makefile文件**
threadpool:threadpool.cc
g++ $^ -o $@ -lpthread
clean:
rm -f threadpool
Task.hpp文件
#pragma once
#include<iostream>
#include<stdio.h>
using namespace std;
class Task
{
private:
int x;int y;
char op;
public:
Task(int _x,int _y,char _op)
:x(_x)
,y(_y)
,op(_op){ }
Task()
{};
void Run()
{
int ret=0;
switch(op){
case '+':
ret=x+y;
break;
case '-':
ret=x-y;
break;
case '*':
ret=x*y;
break;
case '/':
ret=x/y;
break;
case '%':
ret=x%y;
break;
}
printf("%d %c %d = %d\n",x,op,y,ret);
}
};
** threadpool.hpp文件 **
#pragma once
#include<iostream>
#include<queue>
#include<pthread.h>
#include<unistd.h>
using namespace std;
#define NUM 4
template<class T>
class ThreadPool
{
private:
queue<T> q;//任务队列
int thread_num;//线程池的线程数量
pthread_mutex_t lock;//互斥锁
pthread_cond_t cond;//条件变量
public:
ThreadPool(int num=NUM)//初始化变量
:thread_num(num){
pthread_mutex_init(&lock,NULL);
pthread_cond_init(&cond,NULL);
}
bool Empty()
{
return q.size()==0?true:false;
}
static void* Routine(void* arg)//线程执行流
{
pthread_detach(pthread_self());//线程分离
ThreadPool* self=(ThreadPool*)arg;
while(1)
{
self->LockQueue();
while(self->Empty())//任务队列是否为空
{
self->Wait();
}
T data;
self->Pop(data);//取出任务
self->UnlockQueue();
cout<<pthread_self()<<"# ";
//处理任务
data.Run();//处理任务
sleep(1);
}
}
void Wait()//线程等待
{
pthread_cond_wait(&cond,&lock);
}
void LockQueue()//锁住队列
{
pthread_mutex_lock(&lock);
}
void UnlockQueue()//解锁队列
{
pthread_mutex_unlock(&lock);
}
void ThreadPoolInit()
{
pthread_t tid;
for(int i=0;i<thread_num;i++)//创建线程池中的线程
{
pthread_create(&tid,NULL,Routine,(void*)this);
}
}
void Push(const T& in)//将任务推进任务队列中
{
LockQueue();
q.push(in);
UnlockQueue();
SignalThread();
}
void SignalThread()//唤醒cond变量下的线程
{
pthread_cond_signal(&cond);
}
void Pop( T& out)//取出任务队列中的任务
{
out=q.front();
q.pop();
}
~ThreadPool()
{
pthread_mutex_destroy(&lock);
pthread_cond_destroy(&cond);
}
};
threadpool.cc 文件
#include"threadpool.hpp"
#include"Task.hpp"
#include<time.h>
#include<stdlib.h>
int main()
{
ThreadPool<Task> * q=new ThreadPool<Task>();//创建线程池
q->ThreadPoolInit();
srand((long int)time(NULL));
while(1) //主线程往任务队列中放任务
{
char arr[]="+-*/%";
int x=rand()%100+1;
int y=rand()%100+1;
char op=arr[rand()%5];
Task t(x,y,op);//创建任务
q->Push(t);//将任务推送给队列中
}
return 0;
}
运行结果:
版权归原作者 努力学习的少年 所有, 如有侵权,请联系我们删除。