zoukankan      html  css  js  c++  java
  • MFC

    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 }
  • 相关阅读:
    怎么用JQUERY设置div背景图片?
    为什么导入本地jquery.js老是无效?(已解决)
    问题:AJAX的send参数里,空格以及它后面的数据在传递时消失(已解决)
    问题:win7下配置好服务器就是不能查询数据库。(已解决)
    问题:怎么把mysql的系统时间调整为电脑的时间?(已解决)
    jira安装说明
    HTTP 响应时发生错误。这可能是由于服务终结点绑定未使用 HTTP 协议造成的。这还可能是由于服务器中止了 HTTP 请求上下文(可能由于服务关闭)所致。
    C# 清空控制台屏幕内容
    NPOI导出Excel,添加图片和设置格式,添加条形码
    JS简写
  • 原文地址:https://www.cnblogs.com/DuanLaoYe/p/5428993.html
Copyright © 2011-2022 走看看