一 ThreadPool.hpp
#pragma once
#include <iostream>
#include <pthread.h>
#include <string>
#include <vector>
#include <queue>
#include <unistd.h>
using namespace std;
struct ThreadInfo
{
pthread_t tid;
string threadName;
};
static const int num = 5;
template <class T>
class ThreadPool
{
private:
void Lock()
{
pthread_mutex_lock(&_lock);
}
void Unlock()
{
pthread_mutex_unlock(&_lock);
}
void Wakeup()
{
pthread_cond_signal(&_cond);
}
void ThreadSleep()
{
pthread_cond_wait(&_cond, &_lock);
}
bool IsTasksQueueEmpty()
{
return _tasks.empty();
}
T Pop()
{
T task = _tasks.front();
_tasks.pop();
return task;
}
std::string GetThreadName(pthread_t tid)
{
for (const auto &ti : _threads)
{
if (ti.tid == tid)
return ti.threadName;
}
return "None";
}
static void *HandlerTask(void *args)
{
// 局部变量
ThreadPool *tp = static_cast<ThreadPool *>(args);
std::string name = tp->GetThreadName(pthread_self());
cout << "create a new thread: " << endl;
while (1)
{
// 临界资源_tasks,访问时需要加锁
tp->Lock();
while (tp->IsTasksQueueEmpty()) // 有任务才能继续执行,误唤醒
{
tp->ThreadSleep();
}
T t = tp->Pop();
tp->Unlock();
t(); // 处理任务
std::cout << name << " run, "
<< "result: " << t.GetResult() << std::endl;
}
}
public:
ThreadPool(int size = num)
: _threads(size)
{
pthread_mutex_init(&_lock, nullptr);
pthread_cond_init(&_cond, nullptr);
}
~ThreadPool()
{
pthread_mutex_destroy(&_lock);
pthread_cond_destroy(&_cond);
for (int i = 0; i < _threads.size(); ++i)
{
pthread_join(_threads[i].tid, nullptr);
}
}
void start()
{
// 循环创建多线程
for (int i = 0; i < _threads.size(); ++i)
{
_threads[i].threadName = "thread-" + to_string(i);
pthread_create(&(_threads[i].tid), nullptr,
HandlerTask, this);
}
}
void Push(const T &in)
{
Lock();
_tasks.push(in);
Wakeup();
Unlock();
}
private:
vector<ThreadInfo> _threads;
queue<T> _tasks;
pthread_mutex_t _lock;
pthread_cond_t _cond;
};
二 Task.hpp
#pragma once
#include <iostream>
#include <string>
std::string opers="+-*/%";
enum{
DivZero=1,
ModZero,
Unknown
};
class Task
{
public:
//Task(){}
Task(int x=0, int y=0, char op=opers[0]) : data1_(x), data2_(y), oper_(op), result_(0), exitcode_(0)
{
}
void run()
{
switch (oper_)
{
case '+':
result_ = data1_ + data2_;
break;
case '-':
result_ = data1_ - data2_;
break;
case '*':
result_ = data1_ * data2_;
break;
case '/':
{
if(data2_ == 0) exitcode_ = DivZero;
else result_ = data1_ / data2_;
}
break;
case '%':
{
if(data2_ == 0) exitcode_ = ModZero;
else result_ = data1_ % data2_;
} break;
default:
exitcode_ = Unknown;
break;
}
}
void operator ()()
{
run();
}
std::string GetResult()
{
std::string r = std::to_string(data1_);
r += oper_;
r += std::to_string(data2_);
r += "=";
r += std::to_string(result_);
r += "[code: ";
r += std::to_string(exitcode_);
r += "]";
return r;
}
std::string GetTask()
{
std::string r = std::to_string(data1_);
r += oper_;
r += std::to_string(data2_);
r += "=?";
return r;
}
~Task()
{
}
private:
int data1_;
int data2_;
char oper_;
int result_;
int exitcode_;
};
三 main.cpp
#include"ThreadPool.hpp"
#include"Task.hpp"
#include<ctime>
int main()
{
ThreadPool<Task> *tp = new ThreadPool<Task>(5);
tp->start();
srand(time(nullptr)^getpid());
usleep(5000);
cout<<"threadPool start!"<<endl;
while(1)
{
// 1 创建任务,发送任务
int x = rand()%10+1;
int y = rand()%10;
char op = opers[rand()%opers.size()];
Task t(x,y,op);
// 2 发送任务,多线程并发执行任务
tp->Push(t);
std::cout << "main thread make task: " << t.GetTask() << std::endl;
sleep(1);
}
}