1.2线程回收:

首先得知道线程的两个状态:

Joinable 
Detached

简单理解,如果一个线程是joinable的状态,那么这样的线程,就必须使用pthread_join来回收,否则程序结束时,线程所占用的资源不会释放,就会造成内存泄漏。

我们通常在主进程中会阻塞调用pthread_join来等待我们的线程结束。

如果是Detached状态的线程,那么在线程结束后,资源会自动释放,POSIX pthread线程库中,提供下面函数来让线程进入Detached状态:

int pthread_detach(pthread_t thread);

设计中,考虑pthread_joinpthread_detach的特性,分别对成员函数join和析构函数进程封装。

线程创建时默认情况情况下是Joinable状态。

2.线程封装

封装为一个C++ 类需要一些技巧:

  1. 1.Thread是没有拷贝构造和赋值语义的,因此也需要继承自boost::noncopyable
  2. 2.关于pthread_create的第三个参数(返回void*参数为void*的函数指针),因为成员函数会隐式包含this指针作为参数,所以加以static修饰。
  3. 3.对于pthread_create的第四个参数(void *arg作为线程参数),传入this指针方便线程调用成员函数。
  4. 4.使用join()成员函数封装pthread_join(),析构函数使用pthread_detach()处理。
  5. 5.设置run()成员函数为纯虚函数,子类重写run()方法。
  1. class Thread : public boost::noncopyable
  2. {
  3. public :
  4. Thread();
  5. virtual ~Thread();//虚析构
  6. void start();
  7. void join();
  8. virtual void run()=;//纯虚函数
  9. pthread_t getThreadId() const
  10. {
  11. return threadId_;
  12. }
  13. private:
  14. //pthread_create()第三个参数是一个回调函数,void*为返回值和参数
  15. static void *runInThread(void *arg);
  16. pthread_t threadId_;
  17. bool isRunning_;
  18. };
  19. //这里对成员函数进行定义,run()由于是纯虚函数,我们放到子类中重写:
  20. Thread::Thread():isRunning_(false),threadId_(){}//构造函数
  21. Thread::~Thread()//析构函数
  22. {
  23. if(isRunning_)
  24. {
  25. CHECK(!pthread_detach(threadId_));//如果线程正在运行,则让其状态为detached
  26. }
  27. }
  28.  
  29. void *Thread::runInThread(void *arg)
  30. {
  31. Thread *pt =static_cast<Thread*>(arg);//arg即为this指针
  32. pt->run();//调用run方法
  33. return NULL;
  34. }
  35.  
  36. void Thread::start()
  37. {
  38. CHECK(!pthread_create(&threadId_,NULL,Thread::runInThread,this));//创建线程
  39. isRunning_=true;
  40. }
  41.  
  42. void Thread::join()
  43. {
  44. assert(isRunning_);
  45. CHECK(!pthread_join(threadId_,NULL));//回收线程
  46. isRunning_=false;
  47. }

c++ 封装线程库 2的更多相关文章

  1. c++ 封装线程库 3

    1. 继承与重写run方法 我们封装了Thread类,并设置成员函数run()为纯虚函数,因此我们使用类继承,并重写run方法: class IncCount : public Thread//增加计 ...

  2. c++ 封装线程库 0

    1.互斥锁简介 互斥锁主要用于互斥,互斥是一种竞争关系,用来保护临界资源一次只被一个线程访问. POSIX Pthread提供下面函数用来操作互斥锁. int pthread_mutex_init(p ...

  3. c++ 封装线程库 1

    1.Pthread条件变量简介 条件变量也是线程间同步一个重要的内容,如果说互斥是一个种竞争关系,那么条件变量用于协调线程之间的关系,是一种合作关系. 条件变量的应用很多,例如:BlockingQue ...

  4. Linux posix线程库总结

    由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 线程的实现,经历了如下发展阶段: Linu ...

  5. 引擎之旅 Chapter.2 线程库

    预备知识可参考我整理的博客 Windows编程之线程:https://www.cnblogs.com/ZhuSenlin/p/16662075.html Windows编程之线程同步:https:// ...

  6. 【Jetlang】一个高性能的Java线程库

    actor  Jetlang 提供了一个高性能的Java线程库,该库是 JDK 1.5 中的 java.util.concurrent 包的补充,可用于基于并发消息机制的应用. .net的MS CCR ...

  7. Boost线程库学习笔记

    一.创建一个线程 创建线程 boost::thread myThread(threadFun); 需要注意的是:参数可以是函数对象或者函数指针.并且这个函数无参数,并返回void类型. 当一个thre ...

  8. 【Node.js 自己封装的库 http_parse, libuv】

    [Node.js 自己封装的库 http_parse, libuv] Node.js 介绍:一个网络框架,更多:http://www.oschina.net/p/nodejs 官网:http://no ...

  9. Arduino线程库ProtoThreads

    参考: Arduino线程库ProtoThreads 一个“蝇量级” C 语言协程库

随机推荐

  1. Java-马士兵设计模式学习笔记-工厂模式-用Jdom模拟Spring

    一.概述 1.目标:模拟Spring的Ioc 2.用到的知识点:利用jdom的xpath读取xml文件,反射 二.有如下文件: 1.applicationContext.xml <?xml ve ...

  2. Java-马士兵设计模式学习笔记-策略模式-模拟Comparable接口

    一.情况 1.目标:要在专门用于排序数据的DataSorter.java中实现对所有A类,B类,C类,D类等等的排序 2.初步想法:DataSorter.java的代码如下 public class ...

  3. Xamarin Mono for VS开发窗体标题(Title)乱码解决方案

    利用mono for VS开发一个手机程序,结果只有窗体的标题 title部分是乱码,其他所有地方中文都显示正常,很郁闷.百度很久无果.最后发现只要在 VS菜单中 的 文件->高级保存选型中奖编 ...

  4. 知识问答网站---邮件发送失败--debug

    发送邮件失败的原因:授权码过期 注意,邮箱设置的密码是授权码,并不是自己登录的时候用的账号密码.

  5. 深、浅copy

    深.浅copy多用于列表 浅copy:第一层中不变的数据是独立的,可变类型元素指向同一块内存地址 l1 = [1,2,3,["a","b"]] l2 = l1. ...

  6. Mysql--连接查询

    内连接查询 意义:找到表和表之间的关系或者是桥梁.连接查询是查询两个或者两个以上的表时使用的. JOIN|CROSS JOIN| INNER JOIN    通过ON  连接条件(这三个方式都行)一般 ...

  7. C# 与Java初始化顺序及异同(转)

    C#初始化顺序 类成员变量初始化先于类的构造函数 静态成员变量先于实例变量 子类成员变量先于父类成员变量(java相反) 父类构造函数先于子类构造函数 参考实例: using System; //us ...

  8. the ssl module in Python is not available错误解决

    在使用pip安装pymongo的过程中报错,提示如下: $ pip3 install pymongo pip is configured with locations that require TLS ...

  9. Go语言学习教程:管理员登录功能开发

    学习完了数据库操作的知识以后.本节内容,我们将实现管理员登陆功能,涉及到多个模块的代码实现和逻辑处理,以及数据库表的操作,都将在本节内容中进行实现. 管理员结构体定义 首先我们要定义管理员这个实体的结 ...

  10. c语言参考书籍

    很惭愧没能把c++学的很好,毕竟离开始工作只有2年时间,对自己要求不要过高,慢慢来吧.话说知道自己的不足,以后要更加抓紧了!fighting~ 现在计划着把c语言给学习一下了,当然这次指的是深入地学习 ...