看流星社区

 找回密码
 注册账号
查看: 2060|回复: 0

封装线程类的方法

[复制链接]

该用户从未签到

发表于 2017-6-2 13:22:47 | 显示全部楼层 |阅读模式
代码:
// 给主窗口的通知消息
#define WM_CUTTERSTART WM_USER + 100        // wParam == xxx  lParam==xxxx

/*
外面调用这个类时,只需要IsRunning() Startxxx(xxx) Suspendxxx()   Resumexxx() Stopxxx()
*/

/*
m_bContinue在真正的工作代码DoSomething中检测,在退出和类析构时设为FALSE,在Reset时和构造时设为TRUE  标志内部是否继续工作
m_bRunning  在Startxxx Suspendxxx Resumexxx 中检测,在构造时和Reset时设为FALSE,在_ThreadEntry得到WaitForSingleObject时设为TRUE
                        外部通过IsRunning得到是否正在运行

*/
class CMyClass
{
public:
        // 工作退出代码
        enum ExitCode{
                exitSuccess,        // 成功完成任务
                exitUserForce,  // 用户终止
                exitError,  // 源文件出错
        };

        // 构造函数
        CMyClass(HWND hWndNotify); //接收窗口句柄

        // 属性 对外开放
        BOOL IsRunning() const { return m_bRunning; }  //对外

        // 操作  对外开放
        BOOL Startxxx(xxx);
        BOOL Suspendxxx();
        BOOL Resumexxx();
        void Stopxxx();

        // 具体实现
public:
        ~CFileCutter(); //析构

protected:
        // 重置参数信息和状态标志
        void Reset();
        // 真正的工作核心代码
        void DoSomething();

        // 工作线程
        UINT friend _ThreadEntry(LPVOID lpParam);


        // 状态标志
        BOOL m_bContinue;        //  是否继续工作 DoSomething中检测,如果在DoSomething中不m_bContinue,就中止工作
        BOOL m_bRunning;        //  是否处于工作状态

        // 同步以上两组数据
        CRITICAL_SECTION m_cs;        // Data gard

private:
        // 对象的生命周期全局有效的数据
        HWND m_hWndNotify;        // 接受消息通知事件的窗口句柄
        HANDLE m_hWorkEvent;        // 通知开始工作的事件对象句柄
        CWinThread* m_pThread;        // 工作线程
        BOOL m_bSuspend;        // 暂停标志
        BOOL m_bExitThread;        // 退出标志
};

//构造
CMyClass::CMyClass()
{
        // 初始化全局有效变量

        m_hWndNotify = hWndNotify;
        m_bExitThread = FALSE;
        m_bSuspend = FALSE;
        // 创建等待事件对象
        m_hWorkEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);
        // 创建工作线程
        m_pThread = AfxBeginThread(_CutterEntry, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED, NULL);
        m_pThread->m_bAutoDelete = FALSE;
        m_pThread->ResumeThread();

        // 初始化工作期间有效变量
        m_bContinue = TRUE;  //工作函数不被打断,这个标志就为TRUE,在工作函数中检测这个值
        m_bRunning  = FALSE;  //线程函数在WaitForSingleObject,所以还是FALSE
        // 创建关键代码段
        ::InitializeCriticalSection(&m_cs);       
}

// 内部工作线程
UINT _ThreadEntry(LPVOID lpParam)
{
        // 得到CMyClass对象的指针
        CMyClass* pMyClass = (CMyClass*)lpParam;

        // 循环处理用户的工作请求
        while(::WaitForSingleObject(pMyClass->m_hWorkEvent, INFINITE) == WAIT_OBJECT_0 &&
                !pMyClass->m_bExitThread)
        {
                // 设置状态标志,说明正在工作
                ::EnterCriticalSection(&pCutter->m_cs);
                pMyClass->m_bRunning = TRUE;
                :eaveCriticalSection(&pCutter->m_cs);

                // 开始真正的工作
                pMyClass->DoSomething()

                // 准备接受新的工作任务
                pMyClass->Reset(); //这个函数中设置一下各标志的值
        }

        return 0;
}

void CMyClass::Reset()
{
        ::EnterCriticalSection(&m_cs);

        // 重置状态标志
        m_bContinue = TRUE;
        m_bRunning = FALSE;

        :eaveCriticalSection(&m_cs);
}

CMyClass::~CMyClass()
{
        // 设置结束标志
        m_bExitThread = TRUE;

        // 设置强制退出标志
        ::EnterCriticalSection(&m_cs);
        m_bContinue = FALSE;
        :eaveCriticalSection(&m_cs);

        //**********很重要******************************************
        // 防止线程在m_hWorkEvent事件上等待
        ::SetEvent(m_hWorkEvent);

        // 确保工作线程结束
        ::WaitForSingleObject(m_pThread->m_hThread, INFINITE);

        // 释放所有资源
        ::CloseHandle(m_hWorkEvent);
        :eleteCriticalSection(&m_cs);
        delete m_pThread;
}

BOOL CMyClass::Startxxx(xxx)
{
        if(m_bRunning)
                return FALSE;

        // 通知线程开始工作
        ::SetEvent(m_hWorkEvent);
        return TRUE;
}

BOOL CMyClass::Suspendxxx()
{
        if(!m_bRunning)
                return FALSE;

        // 暂停工作线程
        if(!m_bSuspend)
        {
                m_pThread->SuspendThread();
                m_bSuspend = TRUE;
        }
        return TRUE;
}

BOOL CMyClass::Resumexxx()
{
        if(!m_bRunning)
                return FALSE;

        // 唤醒工作线程
        if(m_bSuspend)
        {
                m_pThread->ResumeThread();
                m_bSuspend = FALSE;
        }
        return TRUE;
}

void CMyClass::Stopxxx()
{
        // 设置强制退出标志
        ::EnterCriticalSection(&m_cs);
        m_bContinue = FALSE;
        :eaveCriticalSection(&m_cs);

        // 防止线程处于暂停状态
        ResumeCutter();
}


//-------------------------实现代码-------------------------//

//真正的工作代码
void CMyClass:oSomething()
{
       
        // 通知用户,出错
        :ostMessage(m_hWndNotify, wm_xxx, exitError, 0);



        // 通知用户,开始工作
        :ostMessage(m_hWndNotify, WM_XXXSTART, 0, XX);

       
        // 首先判断是否要求终止执行
        if(!m_bContinue)
        {
                //释放资源
                xxxx;

                if(!m_bExitThread)
                        :ostMessage(m_hWndNotify, WM_XXXXSTOP, XX, XX);
                return;
        }

        // 通知用户,工作完成
        :ostMessage(m_hWndNotify, WM_CUTTERSTOP, exitSuccess, nCompleted);
}
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-19 16:12

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表