c++ 封装线程库 2
1.2线程回收:
首先得知道线程的两个状态:
Joinable
Detached
简单理解,如果一个线程是joinable的状态,那么这样的线程,就必须使用pthread_join来回收,否则程序结束时,线程所占用的资源不会释放,就会造成内存泄漏。
我们通常在主进程中会阻塞调用pthread_join来等待我们的线程结束。
如果是Detached状态的线程,那么在线程结束后,资源会自动释放,POSIX pthread线程库中,提供下面函数来让线程进入Detached状态:
int pthread_detach(pthread_t thread);
设计中,考虑pthread_join和pthread_detach的特性,分别对成员函数join和析构函数进程封装。
线程创建时默认情况情况下是Joinable状态。
2.线程封装
封装为一个C++ 类需要一些技巧:
1.Thread是没有拷贝构造和赋值语义的,因此也需要继承自boost::noncopyable
2.关于pthread_create的第三个参数(返回void*参数为void*的函数指针),因为成员函数会隐式包含this指针作为参数,所以加以static修饰。
3.对于pthread_create的第四个参数(void *arg作为线程参数),传入this指针方便线程调用成员函数。
4.使用join()成员函数封装pthread_join(),析构函数使用pthread_detach()处理。
5.设置run()成员函数为纯虚函数,子类重写run()方法。
class Thread : public boost::noncopyable
{
public :
Thread();
virtual ~Thread();//虚析构
void start();
void join();
virtual void run()=;//纯虚函数
pthread_t getThreadId() const
{
return threadId_;
}
private:
//pthread_create()第三个参数是一个回调函数,void*为返回值和参数
static void *runInThread(void *arg);
pthread_t threadId_;
bool isRunning_;
};
//这里对成员函数进行定义,run()由于是纯虚函数,我们放到子类中重写:
Thread::Thread():isRunning_(false),threadId_(){}//构造函数
Thread::~Thread()//析构函数
{
if(isRunning_)
{
CHECK(!pthread_detach(threadId_));//如果线程正在运行,则让其状态为detached
}
} void *Thread::runInThread(void *arg)
{
Thread *pt =static_cast<Thread*>(arg);//arg即为this指针
pt->run();//调用run方法
return NULL;
} void Thread::start()
{
CHECK(!pthread_create(&threadId_,NULL,Thread::runInThread,this));//创建线程
isRunning_=true;
} void Thread::join()
{
assert(isRunning_);
CHECK(!pthread_join(threadId_,NULL));//回收线程
isRunning_=false;
}
c++ 封装线程库 2的更多相关文章
- c++ 封装线程库 3
1. 继承与重写run方法 我们封装了Thread类,并设置成员函数run()为纯虚函数,因此我们使用类继承,并重写run方法: class IncCount : public Thread//增加计 ...
- c++ 封装线程库 0
1.互斥锁简介 互斥锁主要用于互斥,互斥是一种竞争关系,用来保护临界资源一次只被一个线程访问. POSIX Pthread提供下面函数用来操作互斥锁. int pthread_mutex_init(p ...
- c++ 封装线程库 1
1.Pthread条件变量简介 条件变量也是线程间同步一个重要的内容,如果说互斥是一个种竞争关系,那么条件变量用于协调线程之间的关系,是一种合作关系. 条件变量的应用很多,例如:BlockingQue ...
- Linux posix线程库总结
由于历史原因,2.5.x以前的linux对pthreads没有提供内核级的支持,所以在linux上的pthreads实现只能采用n:1的方式,也称为库实现. 线程的实现,经历了如下发展阶段: Linu ...
- 引擎之旅 Chapter.2 线程库
预备知识可参考我整理的博客 Windows编程之线程:https://www.cnblogs.com/ZhuSenlin/p/16662075.html Windows编程之线程同步:https:// ...
- 【Jetlang】一个高性能的Java线程库
actor Jetlang 提供了一个高性能的Java线程库,该库是 JDK 1.5 中的 java.util.concurrent 包的补充,可用于基于并发消息机制的应用. .net的MS CCR ...
- Boost线程库学习笔记
一.创建一个线程 创建线程 boost::thread myThread(threadFun); 需要注意的是:参数可以是函数对象或者函数指针.并且这个函数无参数,并返回void类型. 当一个thre ...
- 【Node.js 自己封装的库 http_parse, libuv】
[Node.js 自己封装的库 http_parse, libuv] Node.js 介绍:一个网络框架,更多:http://www.oschina.net/p/nodejs 官网:http://no ...
- Arduino线程库ProtoThreads
参考: Arduino线程库ProtoThreads 一个“蝇量级” C 语言协程库
随机推荐
- 100741A Queries
传送门 题目 Mathematicians are interesting (sometimes, I would say, even crazy) people. For example, my f ...
- break跳出多重循环
大家都知道break只能跳出当前的一个循环语句,如果碰到要跳出多个循环体,那么我们就该在循环体开头设置一个标志位,然后使用带此标志位的break语句跳出多重循环 jump: ;i<;i++){ ...
- ubuntu基础知识与技巧
root用户与超级用户的切换 (1) sudo -i (2) sudo su (3) su root 安装升级 查看软件xxx安装内容 dpkg -L xxx 查找软件库中的软件 apt-cac ...
- java.io.FileNotFoundException: res/drawable/title_bar_shadow.9.png
ERROR/AndroidRuntime(803): Caused by: java.io.FileNotFoundException: res/drawable/title_bar_shadow.9 ...
- Grideview总结
http://www.cnblogs.com/sufei/archive/2010/03/27/1698590.html
- GridView控件点击单元格如何获取该列的列标题
本博文Insus.NET教你实现在GridView控件中,用mouse点击某单元格之后,希望能获取到该列的列标题. 创建一个网页,创建一个GridView控件: 去cs绑定数据给GridView控件: ...
- java项目中获取文件路径的几种方法
// 第一种: 2 File f = new File(this.getClass().getResource("/").getPath()); // 结果: /Users/adm ...
- ubuntu - 14.04,如何操作Gnome的任务栏?
搜索到的答案: in gnome classic you must press both the Alt & Super keys at the same time while right-c ...
- THINKPHP 框架的模板技术
//echo C('name'); App/Action/IndexAction.class.php文件夹下的 URL模式 //输出URL模式//echo C('URL_MODEL'),'<br ...
- 区块链中的密码学(-)区块链中运用最广的散列算法-SHA256算法分析与实现
在很多技术人员的眼中,区块链并不是一种新的技术,而是过去很多年计算机技术的组合运用.而在这个方方面面技术的运用上,基于密码学的加密算法可以说是区块链各种特点得以表现的根本,一旦目前使用的加密算法被证实 ...