封装线程类的方法

代码:

// 给主窗口的通知消息
#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;
		::LeaveCriticalSection(&pCutter->m_cs);

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

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

	return 0;
}

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

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

	::LeaveCriticalSection(&m_cs);
}

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

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

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

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

	// 释放所有资源
	::CloseHandle(m_hWorkEvent);
	::DeleteCriticalSection(&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;
	::LeaveCriticalSection(&m_cs);

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


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

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



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

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

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

	// 通知用户,工作完成
	::PostMessage(m_hWndNotify, WM_CUTTERSTOP, exitSuccess, nCompleted);
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值