// 线程池线程个数缺省值
#include <iostream>
#include <vector>
#include <queue>
#include <unistd.h>
using namespace std;
const size_t NUM = 5;
template <class T>
class ThreadPool
{
public:
// 构造函数,负责初始化成员变量和创建线程
ThreadPool(const size_t num = NUM)
: _threadNum(num), _tids(num)
{
pthread_mutex_init(&_lock, nullptr);
pthread_cond_init(&_empty, nullptr);
pthread_t id;
for (size_t i = 0; i < _threadNum; ++i)
{
pthread_create(&id, nullptr, Routine, this);
_tids[i] = id;
}
}
// 析构函数中负责销毁互斥锁、条件变量和线程池中的线程
~ThreadPool()
{
pthread_mutex_destroy(&_lock);
pthread_cond_destroy(&_empty);
for (size_t i = 0; i < _threadNum; ++i)
{
pthread_cancel(_tids[i]);
}
}
// 任务队列判空
bool Empty()
{
return _taskQueue.empty();
}
// 申请任务队列的互斥锁
void Lock()
{
pthread_mutex_lock(&_lock);
}
// 释放任务队列的互斥锁
void UnLock()
{
pthread_mutex_unlock(&_lock);
}
// 任务队列为空时,线程在_empty条件变量下等待
void Wait()
{
pthread_cond_wait(&_empty, &_lock);
}
// 唤醒一个在_empty下等待的线程
void WakeUp()
{
pthread_cond_signal(&_empty);
}
// 外部调用该函数向任务队列中插入一个任务
void Push(const T &task)
{
Lock();
_taskQueue.push(task);
UnLock();
WakeUp();
}
private:
// 线程池中的线程调用该成员函数获得任务队列中的一个任务
void Pop(T &task)
{
task = _taskQueue.front();
_taskQueue.pop();
}
// 线程池中的线程执行该函数不断从任务队列中拿任务并解决任务
static void *Routine(void *arg)
{
pthread_detach(pthread_self());
ThreadPool *argThis = (ThreadPool *)arg;
while (true)
{
argThis->Lock();
while (argThis->Empty())
{
argThis->Wait();
}
T task;
argThis->Pop(task);
argThis->UnLock();
task.Run();
}
}
// 成员变量
vector<pthread_t> _tids; // 记录池中所有线程的线程id
size_t _threadNum; // 记录线程池中线程的数量
queue<T> _taskQueue; // 任务队列,用于存储push进来的任务
pthread_mutex_t _lock; // 保证任务队列数据安全的互斥锁
pthread_cond_t _empty; // 队列为空时线程在该条件变量下等待
};
class Task
{
public:
// 构造函数要求创建任务对象时显示传入相关数据
Task(int x = 0, int y = 0, char op = 0)
: _x(x), _y(y), _op(op)
{
}
// 解决任务的Run函数
void Run()
{
int ret = 0;
switch (_op)
{
case '+':
ret = _x + _y;
break;
case '-':
ret = _x - _y;
break;
case '*':
ret = _x * _y;
break;
case '/':
if (_y == 0)
{
cerr << "div is error" << endl;
return;
}
else
{
ret = _x / _y;
break;
}
case '%':
if (_y == 0)
{
cerr << "div is error" << endl;
return;
}
else
{
ret = _x % _y;
break;
}
default:
cerr << "operation error" << endl;
break;
}
cout << "Thread[" << pthread_self() << "]:" << _x << ' ' << _op << ' ' << _y << ' ' << '=' << ' ' << ret << endl;
}
// 运算数以及运算符
private:
int _x;
int _y;
char _op;
};
int main()
{
srand((size_t)time(nullptr));
char opAll[5] = {'+', '-', '*', '/', '%'};
// 创建一个任务类型为Task的线程池对象
ThreadPool<Task> tp;
// 不断地向线程池对象中派发任务,让里面的线程来解决这个任务
while (true)
{
int x = rand() % 100 + 1;
int y = rand() % 100 + 1;
char op = opAll[rand() % 5];
tp.Push(Task(x, y, op));
sleep(1);
}
return 0;
}
效果
Thread[0x16f54b000]:93 + 8 = 101
Thread[0x16f3a7000]:58 % 35 = 23
Thread[0x16f433000]:36 / 37 = 0
Thread[0x16f4bf000]:77 + 2 = 79
Thread[0x16f31b000]:40 % 79 = 40
Thread[0x16f54b000]:36 * 37 = 1332
Thread[0x16f3a7000]:13 % 45 = 13
Thread[0x16f433000]:63 / 44 = 1
çThread[0x16f4bf000]:11 - 38 = -27
Thread[0x16f31b000]:54 / 6 = 9