**C/C++ 线程池的简单封装
最近在搭建一个服务器,打算把线程池应用进去,根据老师课上所讲和网上前辈们提供的资料对线程池有了以下总结:**
一、线程的创建需要内存资源,线程的创建和销毁需要时间资源
二、线程池作用:
如果项目需要频繁的创建线程来处理任务,那么CPU资源会在线程创建和销毁上浪费许多,所以我们可以先把一定量的线程先创建好并且让它们在没任务的情况下陷入睡眠,有任务时再被唤醒来处理任务;
三、线程池组成部分:
(1) 线程池管理器: 对线程进行创建与管理
(2) 工作线程: 线程池中的线程
(3) 任务接口(任务类内):供线程调度进行任务的执行
(4) 任务队列: 存放没用处理的任务,提供一种缓冲机制
四、 封装源码
1、类声明
#pragma once
#include <queue>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include "CTask.h"
class CThreadPool
{
public:
CThreadPool(int num);
~CThreadPool();
public: // 线程内调用
void lock\_mutex(); // 上锁
void unlock\_mutex(); // 解锁
void wait\_for\_wake(); // 线程进入睡眠,等待被唤醒
void pick\_task(); // 从任务队列内拿任务并执行
int get\_pid();
public:
void work(); // 生成工作线程
void add\_task(CTask\* &task); // 添加任务到任务队列, 并且唤醒一个线程取任务
private:
int initTotalNum; // 初始化线程总数
bool bStop; // 结束标志位
std::queue<CTask\*>task_que; //任务队列
pthread_cond_t cond; //线程唤醒的条件变量
pthread_mutex_t mutex; //互斥锁
pthread_t pid; //线程id
};
2、 类定义
#include "CThreadPool.h"
#include <iostream>
using namespace std;
//void\* start\_routine\_A(void\* arg);
// 核心线程回调函数
void\* start\_routine\_A(void\* arg)
{
CThreadPool\* pool = (CThreadPool\*)arg; //获得本类对象
while (1)
{
//1、 用条件变量阻塞线程(也就是让线程睡眠等待唤醒)
pool->lock\_mutex(); //锁上cond, 保证只能cond被用的情况下不会抢占
cout << pthread\_self() << " is waitting for task..." << endl;
//pool->wait\_for\_wake(pool); //pthread\_cond\_wait()函数被调用,锁会自动解开,返回的时候在被锁上
pool->wait\_for\_wake();
cout << pthread\_self() << " is wake up for task......" << endl;
pool->unlock\_mutex(); //公共条件遍历用完就解开锁,尽可能的缩小锁范围
//2、 线程唤醒后从任务队列内拿任务执行
pool->pick\_task();
cout << "core end." << endl;
}
}
CThreadPool::CThreadPool(int num):initTotalNum(num)
{
//初始化两个锁
pthread\_cond\_init(&this->cond, NULL);
pthread\_mutex\_init(&this->mutex, NULL);
}
void CThreadPool::lock\_mutex()
{
pthread\_mutex\_lock(&this->mutex);
}
void CThreadPool::unlock\_mutex()
{
pthread\_mutex\_unlock(&this->mutex);
}
void CThreadPool::wait\_for\_wake()
{
pthread\_cond\_wait(&this->cond, &this->mutex);
cout << "core Thread is wake up, pid = " << this->pid << endl;
}
void CThreadPool::pick\_task()
{
this->lock\_mutex(); //队列也是公共资源,用之前先上锁
if (!this->task_que.empty())
{
CTask\* t = this->task_que.front(); //从队列拿任务(注意:队列是先进先出,栈是先进后出)
this->task_que.pop(); //拿了就踢出队列
this->unlock\_mutex(); //公共资源用完解锁
t->run();
}
else
{
cout << "wocao?" << endl;
this->unlock\_mutex(); //队列为空就解锁,避免进入死锁
}
}
void CThreadPool::work()
{
// 先创建核心线程
for (int i = 0; i < this->core_num; i++)
{
pthread\_create(&this->pid, NULL, start_routine_A, this);
cout << "The " << i + 1 << " core thread has been created." << endl;
sleep(1);
}
// 初始化当前线程数
this->thread_num = core_num;
}