简单的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++线程类的封装的更多相关文章

  1. 【C/C++开发】C++实现简单的线程类

    C++封装一个简单的线程类 多线程编程简介: 大家在编程时,经常需要在程序中启动一个或多个线程来处理任务,而如果每次都是去调用系统创建线程的API函数来创建,代码量虽不多,但线程的创建和业务逻辑代码就 ...

  2. MFC--串口编程---WIN API的方式将串扣操作封装在线程类中

    串口采集数据 本文档介绍的是如何获取串口原始数据并将原始数据解析成可处理或可展示的数据. 一.串口采集有很多方式: 1).MFC有一个专门的控件,直接编程采集,一个控件只能采集一个串口,而且串口名字比 ...

  3. 转:学习笔记: Delphi之线程类TThread

    学习笔记: Delphi之线程类TThread - 5207 - 博客园http://www.cnblogs.com/5207/p/4426074.html 新的公司接手的第一份工作就是一个多线程计算 ...

  4. 学习笔记: Delphi之线程类TThread

    新的公司接手的第一份工作就是一个多线程计算的小系统.也幸亏最近对线程有了一些学习,这次一接手就起到了作用.但是在实际的开发过程中还是发现了许多的问题,比如挂起与终止的概念都没有弄明白,导致浪费许多的时 ...

  5. Delphi中线程类TThread实现多线程编程2---事件、临界区、Synchronize、WaitFor……

    接着上文介绍TThread. 现在开始说明 Synchronize和WaitFor 但是在介绍这两个函数之前,需要先介绍另外两个线程同步技术:事件和临界区 事件(Event) 事件(Event)与De ...

  6. Delphi中线程类TThread实现多线程编程1---构造、析构……

    参考:http://www.cnblogs.com/rogee/archive/2010/09/20/1832053.html Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大 ...

  7. Android(java)学习笔记62:继承Thread类创建线程类

    package cn.itcast_02; /* * 该类要重写run()方法,为什么呢? * 不是类中的所有代码都需要被线程执行的. * 而这个时候,为了区分哪些代码能够被线程执行,java提供了T ...

  8. 转发 Delphi中线程类TThread 实现多线程编程

    Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到,但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchr ...

  9. Delphi 实现多线程编程的线程类 TThread

    http://blog.csdn.net/henreash/article/details/3183119 Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉 ...

随机推荐

  1. vijosP1687 细菌总数

    vijosP1687 细菌总数 链接:https://vijos.org/p/1687 [思路] 错排公式+高精度. 题目要求排列数目而且不能有Pi==i的情况出现,可以看出这正是1,2,3,4,5, ...

  2. Bzoj 1856: [Scoi2010]字符串 卡特兰数,乘法逆元,组合数,数论

    1856: [Scoi2010]字符串 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1194  Solved: 651[Submit][Status][ ...

  3. 《A First Course in Abstract Algebra with Applications》-chaper1-数论

    由于笔者在别的专栏多次介绍过数论,这里在<抽象代数基础教程>的专栏下,对于chaper1数论这一章节介绍的方式不那么“入门”. 首先来介绍一个代数中常用也是非常重要的证明方法:数学归纳法. ...

  4. 3 视频里weekend05、06、07的可靠性 + HA原理、分析、机制 + weekend01、02、03、04、05、06、07的分布式集群搭建

    现在,我们来验证分析下,zookeeper集群的可靠性 现在有weekend05.06.07 将其一个关掉, 分析,这3个zookeeper集群里,杀死了weekend06,还存活weekend05. ...

  5. [poj 2553]The Bottom of a Graph[Tarjan强连通分量]

    题意: 求出度为0的强连通分量. 思路: 缩点 具体有两种实现: 1.遍历所有边, 边的两端点不在同一强连通分量的话, 将出发点所在强连通分量出度+1. #include <cstdio> ...

  6. 前端学习-使用JS库Leaflet.js生成世界地图并获取标注地址经纬度。

    介绍:Leaflet是一个开源的JavaScript库,对移动端友好且对地图有很好的交互性. 大小仅仅只有 33 KB, 同时具有大多数地图所需要的特点. Leaflet设计的非常简单易懂, 同时具有 ...

  7. mysql2redis

    mysql2redis这个项目主要解决mysql数据跟redis数据同步的问题 目前在测试环境研究这方面的应用,以下是git上面的介绍 git入口    git安装入口 Dependencies pl ...

  8. servletConfig对象

    在Servlet的配置文件中,可以使用一个或多个<init-param>标签为servlet配置一些初始化参数. 当servlet配置了初始化参数后,web容器在创建servlet实例对象 ...

  9. PHP发送邮件类库PHPMailer的简单使用

    最近需要用到发送邮件的功能,原本是用PHP自带的mail()函数发送的.php mail()这个方法非常简单.方便.易用,但是除了网易邮箱.QQ邮箱.GMAIL邮箱等常用的邮箱可以收到之外,经测试HO ...

  10. WCF - 实例与会话

    实例上下文 实例上下文是对服务实例的封装 是WCF管理服务实例生命周期的依托  一个WCF服务通过ServiceHost进行寄宿 开启服务后当接收到请求 则会判断当前是否存在实例上下文 如果存在 则通 ...