吉林市城市建设管理执法局网站,招商网站建设简介,互联网舆情监测系统,网站建设选择今天模拟实现了个线程池#xff0c;怎么说#xff0c;感觉整体还是比较容易的#xff0c;线程池和内存池#xff0c;进程池等等#xff0c;大概就是一个意思#xff0c;例如内存池#xff0c;就是提前申请好内存#xff0c;然后等你用的时候再去其中拿就可以了#xf…今天模拟实现了个线程池怎么说感觉整体还是比较容易的线程池和内存池进程池等等大概就是一个意思例如内存池就是提前申请好内存然后等你用的时候再去其中拿就可以了线程池是一个道理就是现申请好一个等我们有任务时去让线程取任务。代码如下
#pragma once
#include iostream
#include pthread.h
#include vector
#include queue
#include unistd.h
#include thread.hpp
#include myMtx.hpp
#include cond.hpp
using namespace std;
#define NUMPTHREAD 5
#define NUMTAK 5
typedef void *(*func)(void *);
//饿汉单列模型
template class T
class pthreadPool
{
public:static pthreadPoolT *get(){return _mypool;}private:pthreadPool(int nump NUMPTHREAD, int numt NUMTAK) : _numpthread_t(nump), _tasknum(numt){pthread_cond_init(_full, nullptr);pthread_cond_init(_empty, nullptr);pthread_mutex_init(_mtx, nullptr);}public:void start(){_func pthreadPoolT::enter;for (int i 0; i _numpthread_t; i){thread *p new thread(_func, this);_pthread_t.push_back(p);}}void pop(T x){myMtx mtx(_mtx);myCond me(_empty, _mtx);myCond mf(_full, _mtx);while (_task.size() 0){mf.singal();me.wait();}sleep(5);cout 消费 pthread_self() endl;x _task.front();_task.pop();}static void *enter(void *args){pthreadPoolT *td reinterpret_castpthreadPoolT *(args);while (true){T ret;td-pop(ret);cout ret endl;}return nullptr;}// 插入任务void task(const T x){myMtx m(_mtx);myCond me(_empty, _mtx);myCond mf(_full, _mtx);while (_task.size() _tasknum){me.singal();mf.wait();}cout 生产 pthread_self() endl;sleep(5);_task.push(x);}~pthreadPool(){pthread_cond_destroy(_full);pthread_cond_destroy(_empty);pthread_mutex_destroy(_mtx);for (auto e : _pthread_t)delete e;}private:vectorthread * _pthread_t;queueT _task;func _func;int _numpthread_t;int _tasknum;pthread_mutex_t _mtx;pthread_cond_t _full;pthread_cond_t _empty;static pthreadPoolT *_mypool;
};
template class T
class pthreadPool;
template class T
pthreadPoolT *pthreadPoolT::_mypool new pthreadPoolT();
#pragma once
#include iostream
#include pthread.h
class myCond
{
public:myCond(pthread_cond_t cond, pthread_mutex_t mtx) : _mcond(cond), _mtx(mtx){}void wait(){pthread_cond_wait(_mcond,_mtx);}void singal(){pthread_cond_signal(_mcond);}
private:pthread_cond_t _mcond;pthread_mutex_t _mtx;
};
#pragma once
#include iostream
#include pthread.h
class myMtx
{
public:myMtx(pthread_mutex_t mtx) : _mtx(mtx){pthread_mutex_lock(_mtx);std::cout 加锁 std::endl;}~myMtx(){pthread_mutex_unlock(_mtx);std::cout 解锁 std::endl;}private:pthread_mutex_t _mtx;
};
#pragma once
#include iostream
#include pthread.h
class myMtx
{
public:myMtx(pthread_mutex_t mtx) : _mtx(mtx){pthread_mutex_lock(_mtx);std::cout 加锁 std::endl;}~myMtx(){pthread_mutex_unlock(_mtx);std::cout 解锁 std::endl;}private:pthread_mutex_t _mtx;
};
#include pthreadPool.hpp
#include time.hint main()
{srand((size_t)time(nullptr) ^ 1100 1);pthreadPoolint *p pthreadPoolint::get();p-start();while (true){p-task(rand() % 100 1);cout 插入成功 endl;}delete p;return 0;
}
总体实现如上逻辑还是比较像生产消费模型的总体进行了锁的封装没有写打印日志的函数。
实现的时候个人认为可以放任务的队列实现成static如果实现成static的话那么此时的所有对象只有一个任务队列但是话又说回来如果创建多个线程池的对象那么就只有一个任务队列貌似也不符合逻辑有这种想法的其实错了因为线程池就像内存池一样只有一个所以我最后把其设计成了单列模式用的是饿汉模式因为饿汉模式没有线程安全问题所以我用了饿汉模式实现你的单利。这只是个人想法也可以不用把任务队列实现为static。
然后锁和条件变量都是用RAII的风格来实现的这样看代码比较简洁。
实现的注意事项个人认为还是线程访问任务队列的哪里比较绕因为我的每一个线程是封装了的所以他创建线程是调用的函数必须是静态的但是如果这个函数是静态的话那么此时他就不可以访问其他的成员变量了所以此时必须要传this指针才可以有些伙伴可能想的是不封装线程不封装线程其实是一样的如果你把创建线程的函数实现在类内那么就不可以调用也必须是静态成员函数才可以如果实现在类外因为函数中要访问其内部的成员所以此时必须是友元函数才可以但是此时问题又来了因为我们线程池的实现是模版所以你必须把这个函数也实现为模版类型所以这里一定要注意。
以上就是我实现的过程想看源码的朋友可以点这里https://gitee.com/stickykkkkkk/linux/tree/master/dm11-13
最后希望大家能够支持谢谢