C++线程类的封装
简单的C++线程操作的封装,使用了智能指针管理对象的释放。
可运行对象基类
class SimpleRunable:public RefCountedBase
{
public:
SimpleRunable(){}
virtual ~SimpleRunable(){}//必须为虚析构函数否则,子类析构函数无法调用
virtual void OnRun()=;//由线程调用
};
实现SimpleRunable的OnRun就可以交由SimpleThread运行。
多线程类封装
class SimpleThread
{
public:
SimpleThread(void);
~SimpleThread(void); bool Start(RefCountedPtr<SimpleRunable> runable);//创建线程
bool Stop(); //强制关闭线程,不建议使用
bool IsRunning(); //判断是否运行 RefCountedPtr<SimpleRunable> GetRunable();//获取当前可运行任务
HANDLE GetHandle(); //获取线程句柄
DWORD GetId(); // 获取线程id
private:
//禁止赋值构造
SimpleThread(const SimpleThread&);
const SimpleThread& operator=(const SimpleThread&); static void ThreadProc(void* param);
struct ThreadData* m_data;
};
使用方法如下:
class TestRunable:public SimpleRunable
{
public:
void OnRun()
{
for( int i=;i<;++i)
{
printf("t%d\t",i);
}
}
~TestRunable()
{
printf("destroy TestRunable\n");
}
}; static void TestSimpleThread()
{
SimpleThread thread;
CountedPtr<SimpleRunable> runable(new TestRunable);
thread.Start(runable);Sleep(100);
}
SimpleThread类的实现如下:
struct ThreadData
{
ThreadData():m_isRunning(false),m_handle(NULL),m_count()//m_count默认值为1,由SimpleThread所拥有
{}
~ThreadData()
{
}
bool m_isRunning;
HANDLE m_handle; int m_count;//计数
RefCountedPtr<SimpleRunable> m_runable;
}; SimpleThread::SimpleThread(void):m_data(new ThreadData)
{
} SimpleThread::~SimpleThread(void)
{
if (AtomicOps::Decrement(&m_data->m_count)==)
{
delete m_data;
}
} bool SimpleThread::Start(RefCountedPtr<SimpleRunable> runable)
{
//如果正在运行返回false
if (m_data->m_isRunning)
{
return false;
} m_data->m_runable=runable;
AtomicOps::Increment(&m_data->m_count);//该计数由ThreadProc减1 HANDLE handle=(HANDLE)_beginthread(ThreadProc,,m_data);
m_data->m_handle=handle;
if (!handle)
{
AtomicOps::Decrement(&m_data->m_count);//线程创建失败计数减一
return false;
}
else
{
m_data->m_isRunning=true;
return true;
}
} bool SimpleThread::IsRunning()
{
return m_data->m_isRunning;
} RefCountedPtr<SimpleRunable> SimpleThread::GetRunable()
{
return m_data->m_runable;
} HANDLE SimpleThread::GetHandle()
{
if (IsRunning())
return m_data->m_handle;
else
return NULL;
} DWORD SimpleThread::GetId()
{
HANDLE handle=GetHandle();
if(handle)
return GetThreadId(handle);
else
return ;
} bool SimpleThread::Stop()
{
if (m_data->m_isRunning)
{
return CloseHandle(m_data->m_handle)==TRUE;
}
else
return false;
} void SimpleThread::ThreadProc(void* param)
{
ThreadData* data=(ThreadData*)param; RefCountedPtr<SimpleRunable>& runable=data->m_runable;
if (runable)
{
runable->OnRun();
} data->m_isRunning=false;
if(AtomicOps::Decrement(&data->m_count)==)
delete data;
_endthread();
}
C++线程类的封装的更多相关文章
- 【C/C++开发】C++实现简单的线程类
C++封装一个简单的线程类 多线程编程简介: 大家在编程时,经常需要在程序中启动一个或多个线程来处理任务,而如果每次都是去调用系统创建线程的API函数来创建,代码量虽不多,但线程的创建和业务逻辑代码就 ...
- MFC--串口编程---WIN API的方式将串扣操作封装在线程类中
串口采集数据 本文档介绍的是如何获取串口原始数据并将原始数据解析成可处理或可展示的数据. 一.串口采集有很多方式: 1).MFC有一个专门的控件,直接编程采集,一个控件只能采集一个串口,而且串口名字比 ...
- 转:学习笔记: Delphi之线程类TThread
学习笔记: Delphi之线程类TThread - 5207 - 博客园http://www.cnblogs.com/5207/p/4426074.html 新的公司接手的第一份工作就是一个多线程计算 ...
- 学习笔记: Delphi之线程类TThread
新的公司接手的第一份工作就是一个多线程计算的小系统.也幸亏最近对线程有了一些学习,这次一接手就起到了作用.但是在实际的开发过程中还是发现了许多的问题,比如挂起与终止的概念都没有弄明白,导致浪费许多的时 ...
- Delphi中线程类TThread实现多线程编程2---事件、临界区、Synchronize、WaitFor……
接着上文介绍TThread. 现在开始说明 Synchronize和WaitFor 但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区 事件(Event) 事件(Event)与De ...
- Delphi中线程类TThread实现多线程编程1---构造、析构……
参考:http://www.cnblogs.com/rogee/archive/2010/09/20/1832053.html Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大 ...
- Android(java)学习笔记62:继承Thread类创建线程类
package cn.itcast_02; /* * 该类要重写run()方法,为什么呢? * 不是类中的所有代码都需要被线程执行的. * 而这个时候,为了区分哪些代码能够被线程执行,java提供了T ...
- 转发 Delphi中线程类TThread 实现多线程编程
Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchr ...
- Delphi 实现多线程编程的线程类 TThread
http://blog.csdn.net/henreash/article/details/3183119 Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉 ...
随机推荐
- 安装windows系统(win7)
又到了清理电脑,重装系统的时候了.最近被自己电脑折腾得不清,特记录下安装心得,以方便以后. 分区考虑(35G+40G) 35G=16G+4G+5G+10G,其中16G是64位官方旗舰版WIN7刚安装好 ...
- Ubuntu 如何使用apt命令安装、升级、卸载软件
apt-get是一条linux命令,适用于deb包管理式的操作系统,主要用于自动从互联网的软件仓库中搜索.安装.升级.卸载软件或操作系统. apt-get命令一般需要root权限执行,所以一般跟着su ...
- 软件授权协议有什么作用,例如GPL、Apache License、CDDL、EPL这些协议有什么区别?
1.授权协议有什么作用:授权协议就是授予你使用或修改软件等权利,由于软件受到著作权保护,未经授权使用即是侵犯著作权,属于违法行为,所以同意或签署软件授权协议是你使用或修改软件的前提条件.既然是授权协议 ...
- shell脚本采用crontab定时备份数据库日志
测试服务器上才用定时脚本备份一个数据库 并打包压缩成tar避免文件过大 脚本如下: 测试服务器的shell backup_mysql.sh #!/bin/bash BASE_PATH=/alidata ...
- unity3d中namespace的使用注意问题
最近在重构游戏中的老一套逻辑,同时要加入新的功能逻辑,因为各种命名问题,就使用namespace进行控制.但是namespace在unity3d引擎中的使用与一般不同,需要注意一点:要作为Compon ...
- SQL GROUP BY GROUPING SETS,ROLLUP,CUBE(需求举例)
实现按照不同级别分组统计 关于GROUP BY 中的GROUPING SETS,ROLLUP,CUBE 从需求的角度理解会更加容易些. 需求举例: 假如一所学校只有两个系, 每个系有两个专业, 每个专 ...
- 理解事件捕获。在限制范围内拖拽div+吸附+事件捕获
一.实现的效果是在限制范围内拖拽div+吸附+事件捕获. 这里需要理解的是事件捕获,这个事件捕获也是为了兼容div在拖拽过程中,文本不被选中这个问题. 如此良辰美景,拖拽也可以很洒脱哈.先看看图, 二 ...
- (转)关闭WordPress自动加载的Open Sans字体,总是连接googleapi.com,导致打开wordpress很慢
转自http://www.xuanfengge.com/turn-off-automatic-loading-wordpress-open-sans-fonts.html 一.'在网上搜了一番,有四种 ...
- extern用法总结!
extern 在源文件A里定义的函数,在其他源文件中是看不见的(即不能訪问).为了在源文件B里能调用这个函数,应该在B的头部加上一个外部声明: extern 函数原型: 这样,在源文件B里也能够调 ...
- keepalive support-----Programming applications
TCP Keepalive HOWTO Prev Next 4. Programming applications This section deals with programming code ...