目录
一,线程池设计
我们这个简单线程池设计思想就是提前创建好一批线程,在没有任务的时候就在条件变量下等待,有任务了就唤醒线程去执行任务,执行完了之后不要释放,在条件变量下等待执行任务就好了。准点就在这里,线程创建好了之后执完任务不释放,这大大提高了效率。
我们把我们的main函数就当作一个创建任务的线程就好了,创建好了之后就不需要管了,唤醒线程池中等待的线程就好了,交给线程池去处理。线程池就不断的处理任务,处理完后继续等待。
二,线程池应用场景
就目前理解的话,线程池对于那种处理时间短的任务是非常赚的,频繁的短任务,用线程池处理完之后那个线程马上返回线程池继续处理下一个任务,因此如果是许多很长的任务的话就不太适合使用线程池,直接用普通的线程去处理就好了。
三,线程池准备
1,包装一个锁
包装一个生命周期随对象的锁,这里起始时练习一下智能指针的思想,可以完全不搞这一个的,但是我写了,就懒得在该回去了。其实也简单,就是在创建对象的时候在构造函数中加锁,对象处理作用域析构的时候我们在析构函数里面解锁。
#pragma once
#include <iostream>
class Mutex
{
public:
Mutex()
{
pthread_mutex_init(&lock_, nullptr);
}
~Mutex()
{
pthread_mutex_destroy(&lock_);
}
void lock()
{
pthread_mutex_lock(&lock_);
}
void unlock()
{
pthread_mutex_unlock(&lock_);
}
private:
pthread_mutex_t lock_;
};
// 让锁的生命周期最对象的生命周期。
class LockGuard
{
public:
// 构造对象的时候加锁。
LockGuard(Mutex* mutex)
: mutex_(mutex)
{
mutex_->lock();
}
~LockGuard()
{
mutex_->unlock();
}
private:
Mutex *mutex_;
};
2,一个任务类
不然创建任务就是插入数据,处理任务就是拿数据有点太单调了,我们这里任务类不写了,用上一节写的处理+-*/%的简答网络计算器。
#pragma once
#include <iostream>
#include <string>
// 一个任务类,并且他自己实现了处理任务的方法。
class Task
{
public:
Task(int one = 1, int two = 1, char op = '*')
: one_(one), two_(two), op_(op)
{
}
// 析构不需要写。
// 处理任务
int run()
{
int resault = -1;
switch (op_)
{
case '+':
resault = one_ + two_;
break;
case '-':
resault = one_ - two_;
break;
case '*':
resault = one_ * two_;
break;
case '/':
if (two_ == 0)
{
resault = -1;
flag