热线电话:0755-23712116
邮箱:contact@shuangyi-tech.com
地址:深圳市宝安区沙井街道后亭茅洲山工业园工业大厦全至科技创新园科创大厦2层2A
那么为什么我们需要线程池技术呢?多线程编程用的好好的,干嘛还要引入线程池这个东西呢?引入一个新的技术肯定不是为了装酷,肯定是为了解决某个问题的,而服务端一般都是效率问题。
我们可以看到多线程提高了CPU的使用率和程序的工作效率,但是如果有大量的线程,就会影响性能,因为要大量的创建与销毁,因为CPU需要在它们之间切换。线程池可以想象成一个池子,它的作用就是让每一个线程结束后,并不会销毁,而是放回到线程池中成为空闲状态,等待下一个对象来使用。
但是让人遗憾的是,C++并没有在语言级别上支持线程池技术,总感觉C++委员会对多线程的支持像是犹抱琵琶半遮面的羞羞女一样,无法完全的放开。
虽然无法从语言级别上支持,但是我们可以利用条件变量和互斥锁自己实现一个线程池。这里就不得不啰嗦几句,条件变量和互斥锁就像两把利剑,几乎可以实现多线程技术中的大部分问题,不管是生产消费者模型,还是线程池,亦或是信号量,所以我们必须好好掌握好这两个工具。
#ifndef _THREADPOOL_H
#define _THREADPOOL_H
#include <vector>
#include <queue>
#include <thread>
#include <iostream>
#include <condition_variable>
using namespace std;
const int MAX_THREADS = 1000; //最大线程数目
template <typename T>
class threadPool
{
public:
threadPool(int number = 1);
~threadPool();
bool append(T *task);
//工作线程需要运行的函数,不断的从任务队列中取出并执行
static void *worker(void *arg);
void run();
private:
//工作线程
vector<thread> workThread;
//任务队列
queue<T *> taskQueue;
mutex mt;
condition_variable condition;
bool stop;
};
template <typename T>
threadPool<T>::threadPool(int number) : stop(false)
{
if (number <= 0 || number > MAX_THREADS)
throw exception();
for (int i = 0; i < number; i++)
{
cout << "create thread:" << i << endl;
workThread.emplace_back(worker, this);
}
}
template <typename T>
inline threadPool<T>::~threadPool()
{
{
unique_lock<mutex> unique(mt);
stop = true;
}
condition.notify_all();
for (auto &wt : workThread)
wt.join();
}
template <typename T>
bool threadPool<T>::append(T *task)
{
//往任务队列添加任务的时候,要加锁,因为这是线程池,肯定有很多线程
unique_lock<mutex> unique(mt);
taskQueue.push(task);
unique.unlock();
//任务添加完之后,通知阻塞线程过来消费任务,有点像生产消费者模型
condition.notify_one();
return true;
}
template <typename T>
void *threadPool<T>::worker(void *arg)
{
threadPool *pool = (threadPool *)arg;
pool->run();
return pool;
}
template <typename T>
void threadPool<T>::run()
{
while (!stop)
{
unique_lock<mutex> unique(this->mt);
//如果任务队列为空,就停下来等待唤醒,等待另一个线程发来的唤醒请求
while (this->taskQueue.empty())
this->condition.wait(unique);
T *task = this->taskQueue.front();
this->taskQueue.pop();
if (task)
task->process();
}
}
#endif
#include "threadPool.h"
#include <string>
using namespace std;
class Task
{
private:
int total = 0;
public:
void process();
};
//任务具体实现什么功能,由这个函数实现
void Task::process()
{
//这里就输出一个字符串
cout << "task successful! " << endl;
this_thread::sleep_for(chrono::seconds(1));
}
template class std::queue<Task>;
int main(void)
{
threadPool<Task> pool(1);
std::string str;
while (1)
{
Task *task = new Task();
pool.append(task);
delete task;
}
}
以上就是线程池的实现部分,充分利用条件变量和互斥锁来实现,模型可以参考生产消费者模型。以上代码部分来自网络,根据自己的需求更改。