线程池:
* 一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着
监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价。线程池不仅能够保证内核的充分利
用,还能防止过分调度。可用线程数量应该取决于可用的并发处理器、处理器内核、内存、网络sockets等的数量。
* 线程池的应用场景:
* 1. 需要大量的线程来完成任务,且完成任务的时间比较短。 WEB服务器完成网页请求这样的任务,使用线程池技
术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数。 但对于长时间的任务,比如一个
Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。
* 2. 对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。
* 3. 接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情
况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,
出现错误.
* 线程池的种类:
* 线程池示例:
* 1. 创建固定数量线程池,循环从任务队列中获取任务对象,
* 2. 获取到任务对象后,执行任务对象中的任务接口
讲线程池我们先讲一下内存池,池的本质都是为了提高效率,如下图:

可以看出如果我们频繁的申请空间,是非常耗时的,STL容器中就有 内存池,不比每次申请空间都向操作系统要,创建一个内存池,提升效率。线程池如下图:

pthread_pool.hpp
#include<iostream>
#include<queue>
#include<pthread.h>
namespace ns_threadpool
{
template<class T>
class PthreadPool
{
public:
PthreadPool(int num = 5)
:_num(num)
{
pthread_mutex_init(&_mutex,nullptr);
pthread_cond_init(&_cond,nullptr);
}
static void* Rountine(void *args) //因为在类中所以必须要是静态成员,因为有this指针
{
pthread_detach(pthread_self());
PthreadPool<T> *q = (PthreadPool<T> *)args;
for(;;)
{
q->Lock();
while(q->IsEmpty())
{
q->Wait();
}
T t;
q->PopTask(&t);
q->Unlock();
t();
}
}
void InitPthreadPool()
{
pthread_t tid;
for(size_t i = 0; i< _num; ++i)
{
pthread_create(&tid,nullptr,Rountine,(void*)this);
}
}
void PushTask(const T& in)
{
Lock();
_task_queue.push(in);
Unlock();
WackUp();
}
~PthreadPool()
{
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_cond);
}
private:
void Lock()
{
pthread_mutex_lock(&_mutex);
}
void Unlock()
{
pthread_mutex_unlock(&_mutex);
}
void PopTask(T* out)
{
*out = _task_queue.front();
_task_queue.pop();
}
bool IsEmpty()
{
return _task_queue.empty();
}
void Wait()
{
pthread_cond_wait(&_cond,&_mutex);
}
void WackUp()
{
pthread_cond_signal(&_cond);
}
private:
std::queue<T> _task_queue;
int _num;
pthread_mutex_t _mutex;
pthread_cond_t _cond;
};
}
main.cpp
#include "thread_pool.hpp"
#include "Task.hpp"
#include<unistd.h>
#include <ctime>
#include <cstdlib>
using namespace ns_threadpool;
using namespace ns_task;
int main()
{
//
PthreadPool<Task> *tp = new PthreadPool<Task>(3);
tp->InitPthreadPool();
srand((long long)time(nullptr));
while(true)
{
//sleep(1);
//网络
Task t(rand()%20+1, rand()%10+1, "+-*/%"[rand()%5]);
tp->PushTask(t);
sleep(1);
}
return 0;
}
Task.hpp
#pragma once
#include <iostream>
#include <pthread.h>
namespace ns_task
{
class Task
{
private:
int x_;
int y_;
char op_; //+/*/%
public:
// void (*callback)();
Task() {}
Task(int x, int y, char op) : x_(x), y_(y), op_(op)
{
}
std::string Show()
{
std::string message = std::to_string(x_);
message += op_;
message += std::to_string(y_);
message += "=?";
return message;
}
int Run()
{
int res = 0;
switch (op_)
{
case '+':
res = x_ + y_;
break;
case '-':
res = x_ - y_;
break;
case '*':
res = x_ * y_;
break;
case '/':
res = x_ / y_;
break;
case '%':
res = x_ % y_;
break;
default:
std::cout << "bug??" << std::endl;
break;
}
std::cout << "当前任务正在被: " << pthread_self() << " 处理: " \
<< x_ << op_ << y_ << "=" << res << std::endl;
return res;
}
int operator()()
{
return Run();
}
~Task() {}
};
}