首页
学习
活动
专区
圈层
工具
发布
50 篇文章
1
C语言中如何实现数据帧封装与解析
2
【熟视C语言】如何快速的了解一个库函数(C语言讲解,以string.h中的部分库函数为例)
3
C语言代码封装MQTT协议报文,了解MQTT协议通信过程
4
NV12数据格式转H265编码格式实现过程
5
基于Modbus协议实现Openplc与Kingview的仿真通讯与模拟测试
6
onvif协议最新版本_接口协议测试工具
7
linux后台开发常用调试工具
8
C/C++开发人员要了解的几大著名C/C++开源库[通俗易懂]
9
适用于嵌入式环境的加速计算库
10
Linux下WebRTC框架Janus编译过程
11
探索嵌入式应用框架(EAF)
12
[C&C++]联合体union的特征及用其进行传输
13
联合体和结构体一起解析数据
14
国标GB28181协议客户端开发(四)实时视频数据传输
15
6.1 C/C++ 封装字符串操作
17
C语言进阶——自定义类型
18
干货 | 结构体、联合体嵌套使用的一些实用操作
19
C语言的面向对象编程
20
QT应用编程: 编写低功耗BLE蓝牙调试助手(Android系统APP)
21
设计模式之接口隔离原则C++实现
22
嵌入式软件开发的框架思维
23
通过面向对象设计串口协议
24
QT应用编程: 开发串口调试助手
25
一种高效的串口自定义16进制通信协议的嵌入式应用开发解决方案
26
嵌入式中状态机的几种骚操作
27
【干货】用FreeRTOS搭建Event-Driven应用框架
28
嵌入式开发基础之任务管理(线程管理)
29
SIP菜鸟如何学SIP
30
Linux下使用libuvc读取控制USB免驱摄像头
31
Linux 使用strace命令查找进程卡死原因
32
84-OOP之组合
33
如何调试多线程程序
34
GDB多线程调试分析
35
GDB多线程多进程调试
36
一个简单实用的线程基类
37
OpenThread是世界上最舒心的跨平台多线程并发库
38
OpenMiniServer是一个超迷你、 超易用的C++高并发跨平台服务器框架
39
OpenSocket是跨全平台的高性能高并发网络库
40
一个C++多线程TCP服务Demo
41
一文搞懂网络库的分层设计!
42
实现一个接收多路RTP流,输出一路RTMP流的简单MCU
43
谈谈嵌入式应用软件人机界面开发的菜单框架编写
44
union 的概念及在嵌入式编程中的应用
45
让终端支持https,移植OpenSSL和libcurl到嵌入式linux,遇到的问题总结
46
日常工作中的设计:解耦和封装
47
一种简易的嵌入式设备系统日志记录方法
48
PLC和计算机通信的数据采集方法和传输监控的实现(1)
49
C++随笔(五)三种实现串口通信的方式
50
开源一个自己写过的MQTT 客户端调试工具

一个简单实用的线程基类

独立子线程设计 这篇文章介绍了在无法控制子线程生命周期时应该怎么做。

这篇文章介绍线程基类CThreadBase,其将线程资源封装成对象,提供生命周期控制接口,派生类覆盖相应的虚函数进行业务功能实现。

提供接口包括:启动线程Start()、结束线程Stop()、查询运行状态IsRunning()。

启动线程Start(),使用C++11 std::async接口启动线程。

结束线程Stop(),同步接口,线程退出运行时才会返回,有效控制线程的生命周期,同步结束线程对于某些业务场景很重要,比如需要线程结束后才能释放相应的资源。内部使用内核对象Event进行同步。

同时提供三个虚函数供子类覆盖实现:

OnStart()在调用接口Start()后线程运行前调用,其参数strParam是由Start()接口透传过来,在该函数中进行初始化。

OnRun()在线程运行时调用,其参数strParam是由Start接口透传过来,只有OnStart()返回true,才会被调用,线程要处理的工作在该函数中实现。

OnStop()在调用接口Stop()后被调用,该函数重要职责是通知OnRun()退出。

源码包括ThreadBase.h和ThreadBase.cpp,可以复制使用。

ThreadBase.h

代码语言:javascript
复制
#pragma once
#pragma warning ( disable : 4251 )

#include <string>
#include <Windows.h>

#ifndef NDEBUG
#define THREAD_BASE_ASSERT(condition) if (!(condition)) { DebugBreak(); }
#else
#define THREAD_BASE_ASSERT(condition) ((void)0)
#endif

/**
线程基类,提供线程启动(异步)、结束(同步)的功能
*/
class CThreadBase
{
public:
    CThreadBase();
    virtual ~CThreadBase();

public:
    /**
    @name 启动线程
    @param strParam 透传给OnRun函数
    @return 成功 或 失败
    */
    bool Start(const std::string& strParam);

    /**
    @name 同步结束线程
    @param strParam 透传给OnRun函数
    @return 成功 或 失败
    */
    void Stop();

    /**
    @name 查询是否处于运行中
    */
    bool IsRunning();

protected:
    //子类可以覆盖,Start时会调OnStart, strParam与Start参数相同
    virtual bool OnStart(const std::string& strParam);

    //子类可以覆盖,线程启动后会调用OnRun, strParam与Start参数相同
    virtual void OnRun(const std::string& strParam);

    //子类可以覆盖,线程结束时调用
    virtual void OnStop() { }

private:
    static void ThreadEntry(CThreadBase* pThis, std::string strParam);

private:
    bool m_bRunning = false;
    HANDLE m_hSyncStop = NULL;
};

ThreadBase.cpp

代码语言:javascript
复制
#include "ThreadBase.h"
#include <future>

using namespace std;

CThreadBase::CThreadBase()
{
}

CThreadBase::~CThreadBase()
{
    if (m_bRunning)
    {
        THREAD_BASE_ASSERT(false);   //should not reach here
        Stop();
    }
}

bool CThreadBase::Start(const std::string& strParam)
{    
    if (m_bRunning)
    {
        THREAD_BASE_ASSERT(false);   //should not reach here
        Stop();
    }

    if (!OnStart(strParam))
    {
        return false;
    }

    if (m_hSyncStop != NULL)
    {
        THREAD_BASE_ASSERT(false);   //should not reach here
        CloseHandle(m_hSyncStop);
    }
    m_hSyncStop = CreateEvent(NULL, TRUE, FALSE, NULL);
    m_bRunning = true;
    async(launch::async, &CThreadBase::ThreadEntry, this, strParam);
    return true;
}

void CThreadBase::Stop()
{
    if (!m_bRunning)
    {
        return;
    }

    OnStop();

    THREAD_BASE_ASSERT(m_hSyncStop != NULL);
    WaitForSingleObject(m_hSyncStop, INFINITE);
    CloseHandle(m_hSyncStop);
    m_hSyncStop = NULL;
    m_bRunning = false;
}

bool CThreadBase::IsRunning()
{
    return m_bRunning;
}

bool CThreadBase::OnStart(const std::string& strParam)
{
    (void)strParam;
    return true;
}

void CThreadBase::OnRun(const std::string& strParam)
{
    (void)strParam;
    THREAD_BASE_ASSERT(false);   //should not reach here
}

void CThreadBase::ThreadEntry(CThreadBase* pThis, std::string strParam)
{
    pThis->OnRun(strParam);
    THREAD_BASE_ASSERT(pThis->m_hSyncStop != NULL);
    SetEvent(pThis->m_hSyncStop);
}
下一篇
举报
领券