本文章没有知识讲解,只有代码:
#pragma once
#include <iostream>
#include <vector>
#include <queue>
#include <pthread.h>
#include <unistd.h>
#include "Task.hpp"
// 创建固定数量的线程池,循环从任务队列中获取任务队列
// 获取到任务后,执行任务对象中的任务接口
class ThreadInfo
{
// public:
// ThreadInfo(std::string thradname="")
// :_threadname(_threadname)
// {}
public:
std::string _threadname;
pthread_t tid;
};
static const int defaultNum = 10;
template <class T>
class ThreadPool
{
private:
ThreadPool(int num = defaultNum)
: _threads(num)
{
printf("num:%d\n", num);
//如果成员变量使用的是指针的形式
// _mutex=new pthread_mutex_t;
// _cond=new pthread_cond_t;
pthread_mutex_init(&_mutex, nullptr);
pthread_cond_init(&_cond, nullptr);
}
~ThreadPool()
{
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_cond);
//如果成员变量使用的是指针的形式
// delete _mutex;
// delete _cond;
}
ThreadPool(const ThreadPool<T> &) = delete;
const ThreadPool<T> &operator=(const ThreadPool<T> &) = delete;
public:
void Lock()
{
pthread_mutex_lock(&_mutex);
}
void Unlock()
{
pthread_mutex_unlock(&_mutex);
}
void WakeuP()
{
pthread_cond_signal(&_cond);
}
void ThreadSleep()
{
pthread_cond_wait(&_cond, &_mutex);
}
bool QueueIsEmpty()
{
return _task.empty();
}
std::string GetThreadName(pthread_t tid)
{
for (auto &t : _threads)
{
if (t.tid == tid)
return t._threadname;
}
return "None";
}
public:
static void *Handlder(void *args)
{
ThreadPool<T> *tp = static_cast<ThreadPool<T> *>(args);
std::string Threadname = tp->GetThreadName(pthread_self());
// std::cout<<"Handlder"<<std::endl;
while (true)
{
tp->Lock();
while (tp->QueueIsEmpty())
{
tp->ThreadSleep();
}
tp->Unlock();
T t = tp->Pop();
t();
sleep(1);
std::cout << Threadname << ":run" << t.GetResult() << std::endl;
}
return nullptr;
}
void Start()
{
std::cout << "Handlder" << std::endl;
int num = _threads.size();
// printf("num:%d\n",num);
for (int i = 0; i < num; i++)
{
_threads[i]._threadname = "thread-" + std::to_string(i + 1);
// std::cout<<"create before"<<std::endl;
pthread_create(&(_threads[i].tid), nullptr, Handlder, this);
}
}
void Push(const T &t)
{
Lock();
_task.push(t);
WakeuP();
Unlock();
}
T Pop()
{
T out = _task.front();
_task.pop();
return out;
}
//单例模式接口
static ThreadPool<T> *GetInstance()
{
if (tp == nullptr)
{
pthread_mutex_lock(&_lock);
if (tp == nullptr)
{
std::cout << "log:singleton create done first" << std::endl;
tp = new ThreadPool<T>();
}
pthread_mutex_unlock(&_lock);
}
return tp;
}
private:
std::vector<ThreadInfo> _threads;
std::queue<T> _task;
// 锁
pthread_mutex_t _mutex;
// 条件变量
pthread_cond_t _cond;
static ThreadPool<T> *tp;
static pthread_mutex_t _lock;
};
template <class T>
ThreadPool<T> *ThreadPool<T>::tp = nullptr;
template <class T>
pthread_mutex_t ThreadPool<T>::_lock = PTHREAD_MUTEX_INITIALIZER;
#pragma once
#include <iostream>
static const std::string ops = "+-*/%";
enum
{
DIV_ZERO = 1,
MOD_ZERO,
UNKONW,
};
class Task
{
public:
Task()
{
}
Task(int x, int y, char op)
: x_(x), y_(y), op_(op), exitcode_(0), result_(0)
{
}
void run()
{
switch (op_)
{
case '+':
result_ = x_ + y_;
break;
case '-':
result_ = x_ - y_;
break;
case '*':
result_ = x_ * y_;
case '/':
{
if (y_ == 0)
exitcode_ = DIV_ZERO;
else
result_ = x_ / y_;
break;
}
case '%':
{
if (y_ == 0)
exitcode_ = MOD_ZERO;
else
result_ = x_ % y_;
break;
}
default:
exitcode_ = UNKONW;
break;
}
}
void operator()()
{
run();
}
std::string GetResult()
{
std::string ret = "x";
ret += op_;
ret += "y=";
ret += std::to_string(result_);
ret += ",exitcode:";
ret += std::to_string(exitcode_);
return ret;
}
std::string GetTask()
{
std::string r = std::to_string(x_);
r += op_;
r += std::to_string(y_);
r += "=?";
return r;
}
~Task()
{
}
private:
int x_;
int y_;
char op_;
int result_;
int exitcode_;
};
#include"ThreadPool.hpp"
int main()
{
// ThreadPool<Task>* t=new ThreadPool<Task>();
// std::cout<<"init done"<<std::endl;
// t->Start();
ThreadPool<Task>::GetInstance()->Start();
srand(time(nullptr));
while(true)
{
//构建任务
int x=rand()%20+1;
sleep(1);
int y=rand()%10;
char op=ops[rand()%ops.size()];
Task t(x,y,op);
ThreadPool<Task>::GetInstance()->Push(t);
//交给线程池处理
std::cout<<"main thread make task: "<<t.GetTask()<<std::endl;
}
return 0;
}
代码结果:

最后:附上喜欢的蜡笔小新,,我们下篇文章再见!
