C++封装线程类:实现暂停、恢复与安全销毁

Chloe
Chloe
发布时间:2026-10-14| 2人浏览过
原创

在Windows C++开发中,封装具有完整生命周期的线程类可显著简化异步任务管理。本文将演示如何利用MFC的 CWinThread、事件对象(Event)和临界区(CriticalSection),实现一个支持状态检测、暂停、恢复及安全销毁的线程类。

核心设计思路

该封装方案旨在解决多线程编程中的常见痛点:线程状态的准确追踪、工作过程的挂起与唤醒、以及程序退出时资源的彻底清理。主要包含以下技术要点:

  • 状态隔离:将“正在执行”(m_bRunning)与“是否被请求继续”(m_bContinue)分离,避免竞态条件。
  • 同步机制:使用 CRITICAL_SECTION 保护标志位读写;使用 CreateEvent 实现主线程对工作线程的唤醒控制。
  • 生命周期管理:析构函数中通过设置全局退出标志和触发事件,强制解除阻塞,并使用 WaitForSingleObject 确保线程完全退出发后释放句柄。

第1步:定义类接口与成员变量

首先定义类的公共接口和内部私有/受保护成员。外部调用者主要通过 IsRunning()、Startxxx()、Suspendxxx() 等方法与线程交互。

#include <afxwin.h>

// 自定义消息,用于向主窗口汇报进度或错误
#define WM_CUTTERSTART (WM_USER + 100)
class CMyClass 
{
public:
    enum ExitCode {
        exitSuccess,    // 成功完成任务
        exitUserForce,  // 用户强制终止
        exitError       // 运行出错
    };

    explicit CMyClass(HWND hWndNotify);
    ~CMyClass();

    // 状态查询
    BOOL IsRunning() const { return m_bRunning; }

    // 控制操作
    BOOL StartTask();
    BOOL SuspendTask();
    BOOL ResumeTask();
    void StopTask();

protected:
    // 核心工作函数(子类重写此方法填入实际逻辑)
    virtual void DoSomething();
    
    // 辅助重置函数
    void Reset();

private:
    // 线程入口点
    static UINT _ThreadEntry(LPVOID lpParam);

    HWND             m_hWndNotify;   // 接收消息通知的窗口句柄
    HANDLE           m_hWorkEvent;   // 唤醒工作线程的事件
    CWinThread*      m_pThread;      // MFC线程对象
    CRITICAL_SECTION m_cs;           // 互斥锁,保护共享状态

    BOOL             m_bRunning;     // 当前是否正在执行DoSomething
    BOOL             m_bContinue;    // 允许DoSomething继续执行的标志
    BOOL             m_bSuspend;     // 是否处于暂停状态
    BOOL             m_bExitThread;  // 全局退出信号
};

第2步:实现构造函数与初始化

在构造函数中,创建自动重置的事件对象和临界区。MFC的 AfxBeginThread 默认线程会自动删除自身,这里需禁用自动删除以便手动管理生命周期,并立即启动线程进入等待状态。

CMyClass::CMyClass(HWND hWndNotify)
{
    m_hWndNotify = hWndNotify;
    m_bExitThread = FALSE;
    m_bSuspend = FALSE;

    // 创建事件对象:自动重置,初始未置位
    m_hWorkEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
    
    // 创建关键代码段
    ::InitializeCriticalSection(&m_cs);

    // 初始化状态标志
    m_bContinue = TRUE; 
    m_bRunning  = FALSE;

    // 启动线程(CREATE_SUSPENDED确保线程先挂起,但需要Resume才能真正运行入口点逻辑)
    // 注意:此处传入 this 指针供静态函数获取对象实例
    m_pThread = AfxBeginThread(_ThreadEntry, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL);
    if(m_pThread) {
        m_pThread->m_bAutoDelete = FALSE; // 禁止自动删除
        m_pThread->ResumeThread();        // 恢复线程以进入入口循环
    }
}

第3步:实现线程入口与核心循环

线程入口函数 _ThreadEntry 是一个死循环。它主要做两件事:等待外部触发(SetEvent)以及执行具体业务逻辑(DoSomething)。在每次工作结束后,通过 Reset() 清理状态。

UINT CMyClass::_ThreadEntry(LPVOID lpParam)
{
    CMyClass* pThis = static_cast<CMyClass*>(lpParam);

    while(TRUE)
    {
        // 等待唤醒信号或退出信号
        DWORD waitResult = ::WaitForSingleObject(pThis->m_hWorkEvent, INFINITE);
        
        // 如果收到退出信号,直接返回结束线程
        if(pThis->m_bExitThread || waitResult != WAIT_OBJECT_0)
            break;

        // 标记线程进入工作状态
        ::EnterCriticalSection(&pThis->m_cs);
        pThis->m_bRunning = TRUE;
        ::LeaveCriticalSection(&pThis->m_cs);

        // 执行业务逻辑
        pThis->DoSomething();

        // 准备下一次循环
        pThis->Reset();
    }

    return 0;
}

第4步:封装暂停与恢复功能

利用MFC线程对象的 SuspendThread 和 ResumeThread API。需注意判断当前是否处于 m_bRunning 状态,非运行状态下暂停/恢复无意义且可能报错。

// 暂停线程
BOOL CMyClass::SuspendTask()
{
    if(!m_bRunning) return FALSE;
    
    if(!m_bSuspend)
    {
        m_pThread->SuspendThread();
        m_bSuspend = TRUE;
    }
    return TRUE;
}

// 恢复线程
BOOL CMyClass::ResumeTask()
{
    if(!m_bRunning) return FALSE;

    if(m_bSuspend)
    {
        m_pThread->ResumeThread();
        m_bSuspend = FALSE;
    }
    return TRUE;
}

第5步:安全的析构与资源释放

这是最关键的部分。析构函数必须确保:1. 告诉工作线程停止执行(m_bContinue = FALSE);2. 如果线程正卡在 WaitForSingleObject,必须立刻将其唤醒;3. 阻塞直到线程句柄关闭;4. 销毁临界区和句柄。

CMyClass::~CMyClass()
{
    // 1. 设置全局退出标志
    m_bExitThread = TRUE;

    // 2. 设置取消标志,中断正在进行的 DoSomething()
    ::EnterCriticalSection(&m_cs);
    m_bContinue = FALSE;
    ::LeaveCriticalSection(&m_cs);

    // 3. 【重要】唤醒正在 Wait 的线程,使其跳出 while 循环
    ::SetEvent(m_hWorkEvent);

    // 4. 等待线程完全结束
    ::WaitForSingleObject(m_pThread->m_hThread, INFINITE);

    // 5. 释放所有系统资源
    ::CloseHandle(m_hWorkEvent);
    ::DeleteCriticalSection(&m_cs);
    delete m_pThread;
}

总结

通过上述封装,开发者获得了一个类似“即插即用”的后台处理单元。外部只需调用 StartTask、SuspendTask、ResumeTask 即可灵活控制进程。在实际使用中,请继承此类并重写 DoSomething 方法以实现具体的业务逻辑,并注意在处理长耗时操作时需频繁检查 m_bContinue 以确保即时响应停止指令。

以上就是C++封装线程类实现暂停、恢复与安全销毁的详细内容,更多关于C++多线程编程的资料请关注本站其它相关文章!
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。