sudo find ../.. -name Thread.hpp
查找Thread.hpp
cp ../../20240814/mythread/Thread.hpp .
通过cp命令进行拷贝
using namespace std;
void* run(void* args)
{
string message=(const char*)args;
while(true)
{
cout<<message<<endl;
sleep(1);
}
return nullptr;
}
int main()
{
ThreadNs::Thread t1(run,(void*)"thread 1 run");
ThreadNs::Thread t2(run,(void*)"thread 2 run");
t1.start();
t2.start();
t1.join();
t2.join();
return 0;
}
测试线程能否成功创建的代码
线程池效果:
thread-1 start ...
thread-2 start ...
thread-3 start ...
thread-4 start ...
thread-5 start ...
请输入数据1# 1
请输入数据2# 2
请输入要进行的运算# +
thread-3获取了一个任务: 1 + 2 = ? 并处理完成,结果是: 1 + 2 = 3
请输入数据1# ^\Quit (core dumped)
LockGuard.hpp
#pragma once
#include<iostream>
#include<pthread.h>
class Mutex
{
public:
Mutex(pthread_mutex_t* lock_p=nullptr)
:lock_p_(lock_p)
{}
void lock()
{
if(lock_p_)
pthread_mutex_lock(lock_p_);
}
void unlock()
{
if(lock_p_)
{
pthread_mutex_unlock(lock_p_);
}
}
~Mutex()
{}
private:
pthread_mutex_t* lock_p_;
};
//在外部将锁初始化定义好,通过LockGuard的方式保护临界资源
class LockGuard
{
public:
LockGuard(pthread_mutex_t* mutex):mutex_(mutex)
{
mutex_.lock();
}
~LockGuard()
{
mutex_.unlock();
}
private:
Mutex mutex_;
};
ThreadPool.hpp
//写线程池的前提是有线程
#pragma once
#include"LockGuard.hpp"
#include"Thread.hpp"
#include<vector>
#include<queue>
#include<pthread.h>
#include<unistd.h>
using namespace std;
using namespace ThreadNs;
const int gnum=5;
template<class T>
class ThreadPool;
template<class T>
class ThreadData
{
public:
ThreadPool<T>* threadpool;
string name;
public:
ThreadData(ThreadPool<T>* tp,const string& in)
:threadpool(tp),name(in)
{}
};
template<class T>
class ThreadPool
{
private:
static void* handlerTask(void* args)
{
ThreadData<T>* td=(ThreadData<T>* )args;
while(true)
{
//td->threadpool->lockQueue();
T t;
{
LockGuard lockguard(td->threadpool->mutex());
while(td->threadpool->isQueueEmpty())
{
td->threadpool->threadWait();
}
t=td->threadpool->pop();//将任务从公共队列中,拿到当前线程独立的栈结构中
}
//td->threadpool->unlockQueue();
cout<<td->name<<"获取了一个任务: "<<t.toTaskString()<<"并处理完成,结果是: "<<t()<<endl;
//实现多个任务并发处理
}
delete td;
return nullptr;
}
public:
void lockQueue(){pthread_mutex_lock(&_mutex);}
void unlockQueue() {pthread_mutex_unlock(&_mutex);}
bool isQueueEmpty() {return _task_queue.empty();}
void threadWait() {pthread_cond_wait(&_cond,&_mutex);}
T pop()
{
T t=_task_queue.front();
_task_queue.pop();
return t;
}
pthread_mutex_t* mutex()
{
return &_mutex;
}
public:
ThreadPool(const int& num=gnum)
:_num(num)
{
pthread_mutex_init(&_mutex,nullptr);
pthread_cond_init(&_cond,nullptr);
for(int i=0;i<_num;i++)
{
_threads.push_back(new Thread());
}
}
void run()
{
for(const auto& t:_threads)
{
ThreadData<T>* td=new ThreadData<T>(this,t->threadname());
t->start(handlerTask,td);
cout<<t->threadname()<<" start ..."<<endl;
}
}
void push(const T& in)
{
//pthread_mutex_lock(&_mutex);
LockGuard lockguard(&_mutex);
_task_queue.push(in);
pthread_cond_signal(&_cond);
//pthread_mutex_unlock(&_mutex);
}
~ThreadPool()
{
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_cond);
for(const auto& t:_threads) delete t;
}
private:
int _num;
vector<Thread*> _threads;
queue<T> _task_queue;
pthread_mutex_t _mutex;
pthread_cond_t _cond;
};
Task.hpp
#pragma once
#include<cstdio>
#include<iostream>
#include<string>
#include<functional>
using namespace std;
class Task
{
using func_t=function<int(int,int,char)>;
//typedef function<int(int,int)> func_t;
public:
Task()
{}
Task(int x,int y,char op,func_t func):_x(x),_y(y),_op(op),_callback(func)
{}
string operator()()
{
int result=_callback(_x,_y,_op);
//构建结构字符串
char buffer[1024];
snprintf(buffer,sizeof buffer,"%d %c %d = %d ",_x,_op,_y,result);
return buffer;
}
string toTaskString()
{
char buffer[1024];
snprintf(buffer,sizeof buffer,"%d %c %d = ? ",_x,_op,_y);
return buffer;
}
private:
int _x;
int _y;
char _op;
func_t _callback;
};
const string oper="+-*/";
int mymath(int x,int y,char op)
{
int result=0;
switch(op)
{
case '+':
result=x+y;
break;
case '-':
result=x-y;
break;
case '*':
result=x*y;
break;
case '/':
{
if(y==0)
{
cerr<<"div zero error!!!"<<endl;
result=-1;
}
else
result=x/y;
}
break;
case '%':
{
if(y==0)
{
cerr<<"mod zero error!!!"<<endl;
result=-1;
}
else
result=x%y;
}
break;
default:
break;
}
return result;
}
class SaveTask
{
typedef function<void(const string&)> func_t;
public:
SaveTask()
{}
SaveTask(const string &message,func_t func)
:_message(message),_func(func)
{}
void operator()()
{
_func(_message);
}
private:
string _message;
func_t _func;
};
void Save(const string& message)
{
const string target="./log.txt";
FILE* fp=fopen(target.c_str(),"a+");
if(!fp)
{
cerr<<" fopen error "<<endl;
return;
}
fputs(message.c_str(),fp);
fputs("\n",fp);
fclose(fp);
}
Thread.hpp
#pragma once
#include<cassert>
#include<iostream>
#include<string>
#include<functional>
#include<pthread.h>
using namespace std;
namespace ThreadNs
{
typedef function<void*(void*)> func_t;
const int num=1024;
class Thread
{
private:
//在类内创建线程,想让线程执行对应的方法,需要将方法设置为static
static void *start_routine(void* args)//类内成员,有缺省参数!!!
{
Thread* _this=static_cast<Thread*>(args);
//静态方法不能调用成员方法或者成员变量
return _this->callback();
}
public:
//using func_t=function<void*(void*)>;
Thread()
{
char buffer[num];//c99才支持用变量初始化数组
//name_="thread-";
//name_+=to_string(number);
snprintf(buffer,sizeof buffer,"thread-%d",threadnum++);
name_=buffer;
}
void start(func_t func,void *args=nullptr)
{
func_=func;
args_=args;
int n=pthread_create(&tid_,nullptr,start_routine,this);
}
void join()
{
int n=pthread_join(tid_,nullptr);
}
string threadname()
{
return name_;
}
void *callback()
{
return func_(args_);
}
private:
string name_;
pthread_t tid_;
func_t func_;//线程要执行的方法
void *args_;//线程执行时对应的参数
static int threadnum;
};
int Thread::threadnum=1;
}
main.cc
#include"ThradPool.hpp"
#include"Thread.hpp"
#include"Task.hpp"
#include<memory>
#include<unistd.h>
using namespace std;
int main()
{
unique_ptr<ThreadPool<Task> > tp(new ThreadPool<Task>());
tp->run();
int x,y;
char op;
while(1)
{
cout<<"请输入数据1# ";
cin>>x;
cout<<"请输入数据2# ";
cin>>y;
cout<<"请输入要进行的运算# ";
cin>>op;
Task t(x,y,op,mymath);
tp->push(t);
sleep(1);
}
return 0;
}
wc -l *
42 LockGuard.hpp
27 main.cc
4 Makefile
109 Task.hpp
71 Thread.hpp
118 threadpool
114 ThreadPool.hpp
485 total
查看代码行数
添加单例模式(懒汉模式)
ThreadPool.hpp
//写线程池的前提是有线程
#pragma once
#include"LockGuard.hpp"
#include"Thread.hpp"
#include<vector>
#include<queue>
#include<pthread.h>
#include<unistd.h>
using namespace std;
using namespace ThreadNs;
const int gnum=5;
template<class T>
class ThreadPool;
template<class T>
class ThreadData
{
public:
ThreadPool<T>* threadpool;
string name;
public:
ThreadData(ThreadPool<T>* tp,const string& in)
:threadpool(tp),name(in)
{}
};
template<class T>
class ThreadPool
{
private:
static void* handlerTask(void* args)
{
ThreadData<T>* td=(ThreadData<T>* )args;
while(true)
{
//td->threadpool->lockQueue();
T t;
{
LockGuard lockguard(td->threadpool->mutex());
while(td->threadpool->isQueueEmpty())
{
td->threadpool->threadWait();
}
t=td->threadpool->pop();//将任务从公共队列中,拿到当前线程独立的栈结构中
}
//td->threadpool->unlockQueue();
cout<<td->name<<"获取了一个任务: "<<t.toTaskString()<<"并处理完成,结果是: "<<t()<<endl;
//实现多个任务并发处理
}
delete td;
return nullptr;
}
ThreadPool(const int& num=gnum)
:_num(num)
{
pthread_mutex_init(&_mutex,nullptr);
pthread_cond_init(&_cond,nullptr);
for(int i=0;i<_num;i++)
{
_threads.push_back(new Thread());
}
}
void operator=(const ThreadPool &)=delete;
ThreadPool(const ThreadPool &)=delete;
public:
void lockQueue(){pthread_mutex_lock(&_mutex);}
void unlockQueue() {pthread_mutex_unlock(&_mutex);}
bool isQueueEmpty() {return _task_queue.empty();}
void threadWait() {pthread_cond_wait(&_cond,&_mutex);}
T pop()
{
T t=_task_queue.front();
_task_queue.pop();
return t;
}
pthread_mutex_t* mutex()
{
return &_mutex;
}
public:
void run()
{
for(const auto& t:_threads)
{
ThreadData<T>* td=new ThreadData<T>(this,t->threadname());
t->start(handlerTask,td);
cout<<t->threadname()<<" start ..."<<endl;
}
}
void push(const T& in)
{
//pthread_mutex_lock(&_mutex);
LockGuard lockguard(&_mutex);
_task_queue.push(in);
pthread_cond_signal(&_cond);
//pthread_mutex_unlock(&_mutex);
}
~ThreadPool()
{
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_cond);
for(const auto& t:_threads) delete t;
}
static ThreadPool<T>* getInstance()
{
if(nullptr==tp)
{
tp=new ThreadPool<T>();
}
return tp;
}
private:
int _num;
vector<Thread*> _threads;
queue<T> _task_queue;
pthread_mutex_t _mutex;
pthread_cond_t _cond;
//设计静态指针
static ThreadPool<T>* tp;
};
template<class T>
ThreadPool<T>* ThreadPool<T>::tp=nullptr;
main.cc
#include"ThreadPool.hpp"
#include"Thread.hpp"
#include"Task.hpp"
#include<memory>
#include<unistd.h>
using namespace std;
int main()
{
//unique_ptr<ThreadPool<Task> > tp(new ThreadPool<Task>());
//tp->run();
ThreadPool<Task>::getInstance()->run();
int x,y;
char op;
while(1)
{
cout<<"请输入数据1# ";
cin>>x;
cout<<"请输入数据2# ";
cin>>y;
cout<<"请输入要进行的运算# ";
cin>>op;
Task t(x,y,op,mymath);
//tp->push(t);
ThreadPool<Task>::getInstance()->push(t);
sleep(1);
}
return 0;
}
while :; do ps -aL | grep threadpool; sleep 1; echo "##################"; done
监视threadpool进程
//设计静态指针
static ThreadPool<T>* tp;//没有实例化出对象
static mutex _singlock;
};
//只有定义了对象模版才会实例化
template<class T>//对于指针类型明确后才能赋值
ThreadPool<T>* ThreadPool<T>::tp=nullptr;
//void 不明确 void*可以设为指针
template<class T>
mutex ThreadPool<T>::_singlock;