C++封装POSIX 线程库(四)使用封装的线程
2016-07-27 09:04
471 查看
C++封装POSIX 线程库(四)使用封装的线程
本文主要介绍如何使用 C++封装POSIX 线程库(一)互斥锁、C++封装POSIX 线程库(二)条件变量的封装和C++封装POSIX 线程库(三)线程的封装三文中介绍的POSIX Pthread的基本组件(互斥锁,条件变量和线程)C++封装的使用。设计一个场景让我们用到这三个组件:一共启动三个线程,其中两个线程负责互斥地对`count“变量进行increment增量操作,另外一个线程则对count变量进行监视,使用条件变量等待其到达某个值时才唤醒修改count的值。
1. 继承与重写run方法
我们封装了Thread类,并设置成员函数run()为纯虚函数,因此我们使用类继承,并重写run方法://main.cpp class IncCount : public Thread//增加计数线程 { private: int id_; public: IncCount(int id):id_(id){} void run() { for(int i=0;i < 10;i ++) { { MutexLockGuard lock(mutex); count++; if (count == 12) { cond.notify();//通知 } //打印信息方便调试 std::cout<<"thread : "<<id_<<" count : "<< count << std::endl; }//临界区 sleep(1.5);//注:sleep不是同步原语,这里只是为了方便调试 } } }; class WatchCount: public Thread//监视线程 { private: int id_; public: WatchCount(int id):id_(id){} void run() { MutexLockGuard lock(mutex);//加锁 while(count < 12)//这里用while防止虚假唤醒 { cond.wait(); } assert(count>=12); count+=125; std::cout<<"thread : "<<id_<<" count : "<< count << std::endl; } };
2. shared_ptr和多态
用C++封装Pthread组件让我们很容易想到多态这个特性,当然我们完全可以这样写://main.cpp int main() { WatchCount t1(1); IncCount t2(2); IncCount t3(3); t1.start(); t2.start(); t3.start(); t1.join(); t2.join(); t3.join(); return 0; }
如果用多态的话,可以用
vector来保存父类指针,并初始化指向子类引用,不过使用
vector<Thread*>我们时常会有困惑,那就是vector作为栈上变量,其程序结束变量生命期结束,而容器中的指针所指向的对象需要我们手动去
delete,这样就会容易出错。boost库中提供shared_ptr(c++11已经加入std),可以避免这种内存泄露的错误:vector生命期结束,
shared_ptr释放,对象的引用计数变为0,也就自动释放资源了。
//main.cpp { vector< shared_ptr<Thread> > t(3); t[0].reset(new WatchCount(1)); t[1].reset(new IncCount(2)); t[2].reset(new IncCount(3)); for(int i=0;i<3;i++) { t[i]->start(); } for(int i=0;i<3;i++) { t[i]->join(); } }//debug
3. 完整代码
3.1主程序
//main.cpp #include "Thread.h" #include "MutexLock.h" #include "Condition.h" #include <vector> #include <memory> using namespace std; MutexLock mutex;//互斥锁 Condition cond(mutex);//条件变量 int count =0; class IncCount : public Thread { private: int id_; public: IncCount(int id):id_(id){} void run() { for(int i=0;i < 10;i ++) { { MutexLockGuard lock(mutex); count++; if (count == 12) { cond.notify(); } std::cout<<"thread : "<<id_<<" count : "<< count << std::endl; } sleep(1.5); } } }; class WatchCount: public Thread { private: int id_; public: WatchCount(int id):id_(id){} void run() { MutexLockGuard lock(mutex); while(count < 12) { cond.wait(); } assert(count>=12); count+=125; std::cout<<"thread : "<<id_<<" count : "<< count << std::endl; } }; int main() { { vector< shared_ptr<Thread> > t(3); t[0].reset(new WatchCount(1)); t[1].reset(new IncCount(2)); t[2].reset(new IncCount(3)); for(int i=0;i<3;i++) { t[i]->start(); } for(int i=0;i<3;i++) { t[i]->join(); } } return 0; }
3.2Makefile
#Makefile PROGS =main CLEANFILES = core core.* *.core *.o temp.* *.out typescript* \ *.lc *.lh *.bsdi *.sparc *.uw all :${PROGS} CXXFLAGS+=-g -std=c++11 main: main.o Thread.o MutexLock.o Condition.o ${CXX} ${CXXFLAGS} -o $@ $^ -lpthread @rm *.o clean: rm -f ${PROGS} ${CLEANFILES}
4. 参考
1.《Linux多线程服务端编程:使用muduo C++网络库》2.http://www.cnblogs.com/inevermore/p/4008572.html
相关文章推荐
- C++之STL(7) queue队列
- VC++中subclassdlgitem函数的功能及用法
- NYOJ A+B IV 小数相加(大数问题)
- C++ map的基本操作和使用
- C++ 逻辑运算符总结
- C语言实现在控制台同一行覆盖刷新输出,以及'\b'退格控制字符的使用
- C++,C++编程,Windows编程,MFC
- 带分割符的参数提取 C语言
- C++ 11 新特性之类型推断与类型获取
- c语言dfs解决n皇后问题
- c语言dfs解决全排列问题
- C++之STL(6)之 map 与 multimap 关联容器
- C语言空指针总结
- 【学习笔记】 C++里面的绑定类型
- Cpp Primer - constexpr
- 设计模式总结2
- 一起talk C栗子吧(第一百七十八回:C语言实例--字符和字符串输出函数一)
- 李洪强漫谈iOS开发[C语言-024]-表达式与赋值运算符
- C++移位运算符
- Leetcode 48. Rotate Image (Medium) (cpp)