直接上代码
/*
author:wcx
date:2020/4/9
task:声明工作结点,声明线程池类。
name:ThreadPool.h
*/
#ifndef THREADPOOL_H
#define THREADPOOL_H
#include <iostream>
#include <string>
#include <queue>
#include <pthread.h>
#include <thread>
#include <mutex>
using namespace std;
namespace wcx{
class Task{
public:
Task(void *args=nullptr,const string name=""):
args(args),name(name){
}
~Task()=default;
virtual void run()=0; //纯虚函数,必须被overwrite
private:
void *args; //参数
string name;
Task(const Task &);
};
class ThreadPool{
public:
ThreadPool(int threadcnt);
ThreadPool();
int size(); //返回工作队列大小
void start(); //开启线程池
void stop(); //中止所有线程
void addtask(Task *); //添加工作
private:
void createthread(); //创建对应线程
void threadfunc(); //执行线程指向的函数
Task *gettask(); //从等待队列拿出来一个然后执行
private:
// thread *threadhead; //整个线程队列
vector<thread> threadqueue;
int threadcnt;
queue<Task*> taskqueue;
// mutex mt;
pthread_mutex_t mt;
pthread_cond_t conlock;
bool isrunning;
ThreadPool(const ThreadPool &);
};
}
#endif
/*
author:wcx
date:2020/4/9
task:实现线程池类。
name:ThreadPool.cpp
*/
//互斥量和条件变量用在哪: 互斥量用在对task队列的改动,条件变量用在取出task时候的唤醒。
#include "ThreadPool.h"
using namespace wcx;
ThreadPool::ThreadPool(int cnt){
threadcnt=cnt;
}
ThreadPool::ThreadPool(){
threadcnt=10;
}
//返回工作队列大小
int ThreadPool::size(){
pthread_mutex_lock(&mt);
int t=taskqueue.size();
pthread_mutex_unlock(&mt);
return t;
}
//开启线程池
void ThreadPool::start(){
isrunning=true;
createthread();
}
//中止所有线程
void ThreadPool::stop(){
//结束所有线程(等待所有线程的执行完),释放资源
if(!isrunning) return;
isrunning=false;
pthread_cond_broadcast(&conlock);
for(int i=0;i<threadqueue.size();i++){
threadqueue[i].join();
}
cout<<"开始清理"<<endl;
threadqueue.clear();
pthread_mutex_destroy(&mt);
pthread_cond_destroy(&conlock);
return;
}
//从任务队列中取出头部,然后开始执行
void ThreadPool::threadfunc(){
while(isrunning){ //只要线程开着,我会一直轮询
Task *now=gettask();
if(now==NULL){
//返回NULL说明已经stop了,不然不会返回null。
cout<<"线程离开"<<endl;
break;
}
now->run(); //多态
}
}
//创建threadnum数量的线程,用Malloc创建,可能存在问题
void ThreadPool::createthread(){
pthread_mutex_init(&mt,NULL);
pthread_cond_init(&conlock,NULL); //初始化锁变量
threadqueue.resize(threadcnt);
for(int i=0;i<threadcnt;i++){
//出错原因,这个线程还没有运行完就被销毁了。
(threadqueue[i])=thread(&ThreadPool::threadfunc,this);
}
return;
}
//从等待队列拿出来一个然后执行
Task* ThreadPool::gettask(){
//条件变量等待唤醒
Task *task=NULL;
while(true){
pthread_mutex_lock(&mt);
while(isrunning&&taskqueue.empty()){
pthread_cond_wait(&conlock,&mt); //有任务来了被唤醒,stop的时候也唤醒。
}
if(!isrunning){
pthread_mutex_unlock(&mt);
return task;
}
task=taskqueue.front();
taskqueue.pop();
pthread_mutex_unlock(&mt);
return task;
}
}
//添加工作,唤醒线程
void ThreadPool::addtask(Task *t){
pthread_mutex_lock(&mt);
taskqueue.push(t);
pthread_mutex_unlock(&mt);
pthread_cond_signal(&conlock);
}
/*
author:wcx
date:2020/4/9
task:实现线程池类。
name:main.cpp
*/
#include "ThreadPool.h"
int cc=0;
mutex tt;
class Mytask:public wcx::Task{
public:
void run(){
tt.lock();
cout<<++cc<<endl;
cout<<"I'm running!!!"<<endl;
tt.unlock();
return;
}
};
int main(){
Mytask *obj=new Mytask();
wcx::ThreadPool pool(10);
pool.start();
for(int i=1;i<=20;i++){
pool.addtask(obj);
}
while(1){
if(pool.size()==0){
pool.stop();
break;
}
}
cout<<"运行结束"<<endl;
}
程序逻辑:
这个代码是跨平台的,没有特殊的api,重在逻辑。
参考博客:
https://www.cnblogs.com/li-daphne/p/5583224.html
逻辑一致,这里采用了更方便的thread(c++11新特性),存储方式进行了改变。