MIT 2012分布式课程基础源码解析-线程池实现
2016-08-16 03:25
447 查看
主要内容
ScopedLock
队列实现
线程池实现
在正式讲解线程池实现之前,先讲解两个有用的工具类:
ScopedLock
fifo队列
ScopedLock:
ScopedLock是局域锁的实现(我也不知道叫什么,姑且这么说吧),它使用了C++中RAII(Resource acquisition is initialization资源获取即初始化),这种技巧实现的锁可在代码块开始处初始化锁,在代码块结束处释放锁,可省去try catch这样的语句,具体实现如下:
其中宏VERIFY定义如下,这时贯穿于整个项目并最常用的一个宏:
ScopedLock的使用方法如下:
在代码块{}定义一个lock变量即可,在}处便能自动调用析构函数,从而自动释放锁,这种技巧在《c++必知必会》中也是强烈推荐的一种技巧。
fifo队列实现
代码中的fifo队列实现了简单生产者消费者模型,提供了阻塞非阻塞选项,实现代码在fifo.h文件下,我们首先看看类定义:
View Code
该线程池的实现确认令人咋舌,很巧妙的将回调类转换成了内部的job_t类,也不失为一个很好的c++学习案例。
使用该线程池很简单,只需定义好相应的事件回调类,然后初始化线程池,再将回调类添加(addObjJob)到线程池中即可
ScopedLock
队列实现
线程池实现
在正式讲解线程池实现之前,先讲解两个有用的工具类:
ScopedLock
fifo队列
ScopedLock:
ScopedLock是局域锁的实现(我也不知道叫什么,姑且这么说吧),它使用了C++中RAII(Resource acquisition is initialization资源获取即初始化),这种技巧实现的锁可在代码块开始处初始化锁,在代码块结束处释放锁,可省去try catch这样的语句,具体实现如下:
struct ScopedLock { private: pthread_mutex_t *m_; public: ScopedLock(pthread_mutex_t *m): m_(m) { VERIFY(pthread_mutex_lock(m_)==0); } ~ScopedLock() { VERIFY(pthread_mutex_unlock(m_)==0); } };
其中宏VERIFY定义如下,这时贯穿于整个项目并最常用的一个宏:
#ifdef NDEBUG #define VERIFY(expr) do { if (!(expr)) abort(); } while (0) #else #define VERIFY(expr) assert(expr) #endif
ScopedLock的使用方法如下:
void func() { ...... { ScopedLock lock(&m_); ...... } ...... }
在代码块{}定义一个lock变量即可,在}处便能自动调用析构函数,从而自动释放锁,这种技巧在《c++必知必会》中也是强烈推荐的一种技巧。
fifo队列实现
代码中的fifo队列实现了简单生产者消费者模型,提供了阻塞非阻塞选项,实现代码在fifo.h文件下,我们首先看看类定义:
//线程执行方法,while循环中获取队列中的工作,因为队列默认是阻塞队列 //线程在没获取到工作时,将阻塞在相应的条件变量上 static void * do_worker(void *arg) { ThrPool *tp = (ThrPool *)arg; //将this转换为ThrPool指针 while (1) { ThrPool::job_t j; if (!tp->takeJob(&j)) break; //die (void)(j.f)(j.a); //执行工作 } pthread_exit(NULL); } //if blocking, then addJob() blocks when queue is full //otherwise, addJob() simply returns false when queue is full ThrPool::ThrPool(int sz, bool blocking) : nthreads_(sz),blockadd_(blocking),jobq_(100*sz) { pthread_attr_init(&attr_); pthread_attr_setstacksize(&attr_, 128<<10); for (int i = 0; i < sz; i++) { pthread_t t; //注意这里函数是do_worker,添加的参数为this,这样在do_worker函数中方便取出更多的信息 VERIFY(pthread_create(&t, &attr_, do_worker, (void *)this) ==0); th_.push_back(t); } } //IMPORTANT: this function can be called only when no external thread //will ever use this thread pool again or is currently blocking on it ThrPool::~ThrPool() { for (int i = 0; i < nthreads_; i++) { job_t j; j.f = (void *(*)(void *))NULL; //poison pill to tell worker threads to exit jobq_.enq(j); } for (int i = 0; i < nthreads_; i++) { VERIFY(pthread_join(th_[i], NULL)==0); } VERIFY(pthread_attr_destroy(&attr_)==0); } //添加工作的私有类,初始化job_t类,并添加到队列中 bool ThrPool::addJob(void *(*f)(void *), void *a) { job_t j; j.f = f; j.a = a; return jobq_.enq(j,blockadd_); } //获取队列中的工作回调,注意传入的是指针 bool ThrPool::takeJob(job_t *j) { jobq_.deq(j); return (j->f!=NULL); }
View Code
该线程池的实现确认令人咋舌,很巧妙的将回调类转换成了内部的job_t类,也不失为一个很好的c++学习案例。
使用该线程池很简单,只需定义好相应的事件回调类,然后初始化线程池,再将回调类添加(addObjJob)到线程池中即可
相关文章推荐
- MIT 2012 分布式课程基础源码解析-底层通讯实现
- MIT 2012分布式课程基础源码解析一-源码概述
- MIT 2012分布式课程基础源码解析-事件管理封装
- 源码解析线程池调度器之任务延迟调度实现机制
- fastjson深度源码解析- 词法和语法解析(二) - 基础类型实现解析
- 秋色园QBlog技术原理解析:博客一键安装工具技术实现[附源码下载]
- Delphi实现线程池组件(完整源码)
- QT源码解析(五)QLibrary跨平台调用动态库的实现
- 程序基础设计模式的解析和实现(C++)之二十-Visitor模式
- 浅论计算机基础课程远程教学系统的设计和实现
- php与memcached服务器交互的分布式实现源码分析[memcache版]
- 使用Android自带Gallery组件实现CoverFlow,源码+解析
- MVC架构探究及其源码实现(1)-理论基础
- PHP与Memcached服务器交互的分布式实现源码分析
- GeoServer源码解析和扩展 (一)基础篇
- 经过一周的挣扎,目前天气预报抓取解析插入数据库的功能已经大致实现,附项目源码
- java基础之:多线程实现/启动/状态+同步+线程池
- Cassandra 源码解析 3: 分布式hashtable(DHT) 和 Locator
- 设计模式精解-GoF 23种设计模式解析附C++实现源码
- php与memcached服务器交互的分布式实现源码分析[memcache版]