Pthread库是posix linux的线程库,调用接口如下,我们模仿JDK,对Thread进行封装,具体的业务逻辑只需要如同Thread一样实现run方法即可。

线程操纵函数(简介起见,省略参数)

pthread_create():创建一个线程
pthread_exit():终止当前线程
pthread_cancel():中断另外一个线程的运行
pthread_join():阻塞当前的线程,直到另外一个线程运行结束
pthread_attr_init():初始化线程的属性
pthread_attr_setdetachstate():设置脱离状态的属性(决定这个线程在终止时是否可以被结合)
pthread_attr_getdetachstate():获取脱离状态的属性
pthread_attr_destroy():删除线程的属性
pthread_kill():向线程发送一个信号

 首先,构造一个run接口如下:


class TC_Runable
{
public:
    virtual ~TC_Runable(){};
    virtual void run()
= 0;
};


声明线程基础类:
/**
 * 线程基类.
 * 线程基类,所有自定义线程继承于该类,同时实现run接口即可,  
 * 可以通过TC_ThreadContorl管理线程。
 */
class TC_Thread : public TC_Runable
{
public:

     /**
     * @brief  构造函数
      */
     TC_Thread();

     /**
     * @brief  析构函数
      */
     virtual ~TC_Thread(){};

     /**
     * @brief  线程运行
      */
     TC_ThreadControl start();

    /**
     * @brief  获取线程控制类.
     *
     * @return ThreadControl
     */
    TC_ThreadControl getThreadControl() const;

    /**
     * @brief  线程是否存活.
     *
     * @return bool 存活返回true,否则返回false
     */
    bool isAlive() const;

     /**
     * @brief  获取线程id.
      *
      * @return pthread_t 线程id
      */
     pthread_t id()
return _tid;
}

protected:

     /**
      * @brief  静态函数, 线程入口.
      * 
      * @param pThread 线程对象
      */
     static void threadEntry(TC_Thread *pThread);

     /**
     * @brief  运行
      */
    virtual void run()
= 0;

protected:
    /**
     * 是否在运行
     */
    bool            _running;

    /**
     * 线程ID
     */
    pthread_t      _tid;

    /**
     * 线程锁
     */
    TC_ThreadLock   _lock;
};

根据Pthread提供的接口实现该Thread类。

线程构造函数:
TC_Thread::TC_Thread() : _running( false), _tid(-1)
{
}
初始化tid为-1,线程状态running为false。


线程执行入口,该方法声明的时候必须为静态方法,因为该方法符合pthread_create方法中的函数指针的类型,该方法将会回调thread的具体的子类重载的run方法,thread子类的实例通过指针传递进来。

void TC_Thread::threadEntry( TC_Thread *pThread)
{
    pThread->_running = true;

    {
        TC_ThreadLock::Lock sync(pThread-> _lock);
        pThread-> _lock.notifyAll();
    }

    try
    {
        pThread->run();
    }
    catch(...)
    {
        pThread-> _running = false;
        throw;
    }
    pThread->_running = false;
}


通过调用start方法线程开始执行,但并不负责具体的执行逻辑,所以该方法对于start来说是通过的,是调用pthread_ctreat的地方,在该方法中,会调用this.threadEntity函数,通过其回调this.run()
TC_ThreadControl TC_Thread::start()
{
    TC_ThreadLock::Lock sync(_lock);

    if(_running)
    {
        throw TC_ThreadThreadControl_Exception("[TC_Thread::start]
thread has start");
    }

    int ret
pthread_create(&_tid ,
                   0,
                   ( void *(*)( void *))& threadEntry,
                   ( void *) this);

    if(ret
!= 0)
    {
        throw TC_ThreadThreadControl_Exception("[TC_Thread::start]
thread start error", ret);
    }

    _lock.wait();

    return TC_ThreadControl(_tid);
}


获取线程控制工具类
TC_ThreadControl TC_Thread::getThreadControl () const
{
    return TC_ThreadControl(_tid);
}


判断线程当前状态。
bool TC_Thread::isAlive() const
{
    return _running;
}

整个线程类封装设计的难点在于,如果保证running的同步,我们必须保证线程真正在执行run方法的时候,该running设置为true,也就是说不能单纯的在start中变更该状态,因为此时有可能threadEntity并没有被执行(Pthread_creat)



在start方法中,首先便获取锁并顺序执行,但是start方法并不返回将wait住(3)(因为此事线程提方法并不一定成功执行,也就是说start能够返回的标志是该线程状态必须为running,否则在业务层面执行完start方法紧接着判断线程isalive却返回false会给调用者带来迷茫,甚至导致重复启动),threadEntity执行时表明pthread_create方法已经开始执行了,新线程执行OK,此时该方法将running设置为true(1),并且试图获取锁,此时如果wait已经执行,则获取锁操作可以成功,如果wait不成功,则会阻塞在这里等待wait操作的到来释放锁。

    {
        TC_ThreadLock::Lock sync(pThread-> _lock);
        pThread-> _lock.notifyAll();
    }

这个大括号很重要,表示sync的生命周期在大括号结束的时候会释放,锁释放代表着notifyAll生效(真正的通知wait解除阻塞是在锁释放的时候进行的,因为wait需要重新获取锁),此时running为true,start方法可以安全返回了。当方法进行完之后,将running重新设置为false(2)。

【C/C++开发】C++ Thread对象封装的更多相关文章

  1. day17-Python运维开发基础(类的封装 / 对象和类的相关操作、构造方法)

    1. 类的封装及相关操作 # ### oop 面向对象程序开发 """ #用几大特征表达一类事物称为一个类,类更像是一张图纸,表达的是一个抽象概念 "" ...

  2. ASP.NET开发,简化与封装

    ASP.NET开发,简化与封装 微软的ASP.NET的开发,就是面向对象的编程,当然前端也能体验至面向对象的话,使用Web控件也必须的. 任一控件,我们均可以在后端.aspx.cs或.aspx.vb程 ...

  3. 上门洗车APP --- Androidclient开发 之 网络框架封装介绍(二)

    上门洗车APP --- Androidclient开发 之 网络框架封装介绍(二) 前几篇博文中给大家介绍了一下APP中的基本业务及开发本项目使用的网络架构: 上门洗车APP --- Androidc ...

  4. 第25课 std::thread对象的析构

    一. 线程的等待与分离 (一)join和detach函数 1. 线程等待:join() (1)等待子线程结束,调用线程处于阻塞模式. (2)join()执行完成之后,底层线程id被设置为0,即join ...

  5. JS 对象封装的常用方式

    JS是一门面向对象语言,其对象是用prototype属性来模拟的,下面,来看看如何封装JS对象. 常规封装 function Person (name,age,sex){ this.name = na ...

  6. Javascript的对象封装和继承有哪些方法?优劣分别是什么?

    1.对象封装方法 (1)原始模式生成对象 直接将我们的成员写入对象中,用函数返回. 缺点:很难看出是一个模式出来的实例. function Stu(name, score) {             ...

  7. jfinal对象封装Record原理

    /*DbPro.class*/ public transient Record findFirst(String sql, Object paras[]{ List result = find(sql ...

  8. Ajax发送FormData对象封装的表单数据

    前端页面: <!doctype html> <html lang="en"> <head> <meta charset="UTF ...

  9. IOS开发之类和对象

    IOS开发之类和对象 OC和Java一样都是一种面向对象的语言,从今天開始我和大家一起来系统学习这样的面向对象的语言oc,欢迎大家什么问题和我一起探讨和学习. OC定义类有两个步骤:1.接口部分(通俗 ...

随机推荐

  1. idea创建springmvc项目创部署成功,但访问controller层报错404

    这个问题网上有很多解决问题,检查配置文件是否正确?controller注解是否扫描?项目启动是否成功等等. 访问报错404,而且后台也没错误,归根结底还是访问路径错了. 1.如图,idea配置tomc ...

  2. 斐波那契数列 矩阵乘法优化DP

    斐波那契数列 矩阵乘法优化DP 求\(f(n) \%1000000007​\),\(n\le 10^{18}​\) 矩阵乘法:\(i\times k\)的矩阵\(A\)乘\(k\times j\)的矩 ...

  3. 【IOI2019】2048矩形模拟

    /* dos windows 25*80 */ #include <algorithm> #include <windows.h> #include <iostream& ...

  4. CF891C Envy【最小生成树】

    题目链接 我们知道,根据Kruskal的贪心,对于最小生成树,每一种权值的边数是一样的,而且如果将\(\leq x\)的边做最小生成树,合法方案的联通性是一样的.所以我们可以对于所有边分开考虑. 对于 ...

  5. Java的 「 “ 结构体 ”」 与 「 “ 自定义排序 ” 」

    Java里面的结构体可以靠class来实现,如果相对结构体进行排序,需要写一个接口,class 自定义的名字 implements Comparator<结构体(自己定义的class类的名字)& ...

  6. Zabbix监控win10系统

    Zabbix监控win10系统 1. 在win10下安装zabbix-agent zabbix-agent下载地址:https://www.zabbix.com/downloads/4.2.6/zab ...

  7. 比Excel还简单的SQL语句查询

    大家好,我是jacky朱元禄,很高兴继续跟大家分享<MySQL数据分析实战>系列课程,前面的课程jacky分享了数据层面增删改查中的增删改,下面的课程我们要说增删改查的这个查,jacky说 ...

  8. docker搭建hadoop HA出错问题总结记录。

    错误1: ssh连接云主机: ssh root@39.106.xx.xx 报错:THE AUTHENTICITY OF HOST XX CAN’T BE ESTABLISHED 解决办法: ssh - ...

  9. dsu on tree学习笔记

    前言 一次模拟赛的\(T3\):传送门 只会\(O(n^2)\)的我就\(gg\)了,并且对于题解提供的\(\text{dsu on tree}\)的做法一脸懵逼. 看网上的其他大佬写的笔记,我自己画 ...

  10. pimpleFoam求解器 vs simpleFoam求解器 vs pisoFoam求解器 vs icoFoam

    翻译自:CFD-online 帖子地址:http://www.cfd-online.com/Forums/openfoam-solving/68072-pimplefoam-vs-simplefoam ...