MFC - 封装线程类: CThread
CThread.h
1 #ifndef _THREAD_H_2016_04_24 2 #define _THREAD_H_2016_04_24 3 #pragma once 4 5 class CThread 6 { 7 public: 8 CThread(); 9 ~CThread(); 10 11 public: 12 void fnStart(DWORD dwCreationFlags = 0); // 开始线程 13 void fnStop(); // 停止线程 14 void fnSuspend(); // 挂起线程 15 void fnResume(); // 恢复线程 16 virtual void fnRun() = 0; // 纯虚函数, 在派生类重载fnRun()函数, 利用C++的多态, 实际执行派生类的fnRun() 17 virtual void fnSetThreadData(DWORD dwParam); // 设置: m_dwData 18 virtual DWORD fnGetThreadData(); // 获取: m_dwData 19 20 private: 21 static DWORD WINAPI fnThreadProc(LPVOID lpParameter); 22 23 public: 24 HANDLE m_hThread; // 线程句柄 25 DWORD m_dwThreadId; // 线程ID 26 BOOL m_bIsExit; // 退出标识 27 BOOL m_bIsSuspend; // 挂起标识 28 DWORD m_dwData; // 如果需要外部传递数据进来: 29 // 1. 通过重载fnSetThreadData()设置m_dwData; 30 // 2. 通过fnGetThreadData()获取m_dwData; 31 // 3. 在派生类中重载fnRun时, 使用m_dwData; 32 }; 33 34 #endif //_THREAD_H_2016_04_24
CThread.cpp
1 #include "stdafx.h" 2 #include "Thread.h" 3 4 5 CThread::CThread() 6 { 7 m_hThread = NULL; // 线程不存在 8 m_dwThreadId = 0; 9 m_bIsExit = FALSE; // 未退出 10 m_bIsSuspend = FALSE; // 未挂起 11 } 12 13 CThread::~CThread() 14 { 15 fnStop(); // 结束线程 16 } 17 18 // 线程回调函数 19 DWORD WINAPI CThread::fnThreadProc(LPVOID lpParameter) 20 { 21 CThread *pThis = (CThread*)lpParameter; 22 ASSERT(pThis); 23 while ( !pThis->m_bIsExit ) 24 { 25 pThis->fnRun(); // 线程真正在fnRun()函数内执行 26 } 27 return 88; 28 } 29 30 // 设置线程数据 31 void CThread::fnSetThreadData(DWORD dwParam) 32 { 33 if (m_dwData != dwParam) 34 { 35 m_dwData = dwParam; 36 } 37 } 38 39 // 获取线程数据 40 DWORD CThread::fnGetThreadData() 41 { 42 return m_dwData; 43 } 44 45 // 开始线程 46 void CThread::fnStart(DWORD dwCreationFlags) 47 { 48 if (m_hThread) return; // 如果线程存在,则不再创建 49 m_bIsExit = FALSE; // 重置退出标识 50 51 m_bIsSuspend = FALSE; // 重置挂起标识 52 m_bIsSuspend = dwCreationFlags == CREATE_SUSPENDED ? TRUE : FALSE; // 如果dwCreationFlags == CREATE_SUSPENDED, 则m_bIsSuspend == TRUE 53 // 线程处于挂起状态, fnStart()后需要调用fnResumeThread()恢复运行 54 HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)fnThreadProc, (LPVOID)this, dwCreationFlags, 0); 55 ASSERT(hThread); 56 m_hThread = hThread; 57 } 58 59 // 停止线程 60 void CThread::fnStop() 61 { 62 if ( m_hThread ) 63 { 64 fnResume(); // 防御性编程: 此处必须处理一次【恢复线程】操作, 防止线程在【挂起】状态下阻塞在WaitForSingleObject(), 无法正常退出; 65 66 /* 67 m_bIsExit == TRUE; 线程执行体内循环结束, 所以必须放在fnResume()后执行; 68 目的 : 是保证线程在正常运行的状态下的正常退出; 线程在挂起状态下且m_bIsExit==TRUE 线程会阻塞在 69 WaitForSingleObject(), 无法正常退出... 70 */ 71 72 m_bIsExit = TRUE; 73 WaitForSingleObject(m_hThread, INFINITE); 74 CloseHandle(m_hThread); 75 m_hThread = NULL; 76 } 77 } 78 79 // 挂起线程 80 void CThread::fnSuspend() 81 { 82 if (NULL == m_hThread) return; // 如果线程不存在, 立即返回 83 if (TRUE == m_bIsSuspend) return; // 如果挂起, 则立即返回 84 SuspendThread(m_hThread); // 挂起线程 85 m_bIsSuspend = !m_bIsSuspend; // TRUE: 标识线程已挂起 86 } 87 88 // 恢复线程 89 void CThread::fnResume() 90 { 91 if (NULL == m_hThread) return; // 如果线程不存在, 立即返回 92 if (FALSE == m_bIsSuspend) return; // 如果未挂起, 则立即返回 93 ResumeThread(m_hThread); // 恢复线程 94 m_bIsSuspend = !m_bIsSuspend; // FALSE: 标识线程已恢复 95 }