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 }
时间: 2024-10-06 08:05:50

MFC - 封装线程类: CThread的相关文章

c++封装线程类

在csapp学习或者其他linux底层编程的过程中,一般都会举一些多线程或多进程的例子,配合底层同步原语.系统调用api来解释怎么创建多线程/多进程. 但是这些例子和实际项目中所用到的多线程/多进程编程知识有很大的距离(小例子很好理解,但是为了完成一个任务基本就没有什么思路了). 我学习多线程/多进程编程由4个月了,一开始就知道由线程池实现的问题(面试现场白板撸代码的),可是怎么都实现不了, 这一次说什么都要学会(那怕是从别的blog中抄来的代码,直到解释的通就行.加油!!). c++封装线程类

MFC--串口编程---WIN API的方式将串扣操作封装在线程类中

串口采集数据 本文档介绍的是如何获取串口原始数据并将原始数据解析成可处理或可展示的数据. 一.串口采集有很多方式: 1).MFC有一个专门的控件,直接编程采集,一个控件只能采集一个串口,而且串口名字比如是COM20可能就打不开(这里我没有实践,师兄给这样说的),波特率太高读数会出错. 2).利用Windows API通信函数(该工程里面就采用的这种方式) 3).利用Visual C++的标准通信函数_inp._inpw._inpd._outp等直接对串口进行操作. 4).第三方编写的通信类. 二

MFC常用的类详细介绍

常用的MFC类 CRuntimeClass结构 在CRuntimeClass结构中定义了类名.对象所占存储空间的大小.类的版本号等成员变量及动态创建对象.派生关系判断等成员函数.每一个从CObject类派生的类都有一个CRuntimeClass结构同它关联,以便完成在运行时得到对象的信息或基类的信息. 要使用CRuntimeClass结构,必须结合使用RUNTIME_CLASS()宏和其他有关运行时类型识别的MFC宏. CObject类 MFC的CObject类为程序员提供了对象诊断.运行时类型

MFC的socket类

MFC的socket类,部分封装了这些以WSA开头的socket函数,使用更加简单方便,只适合小型的网络通信编程的开发 1.CAsyncSocket类 -部分封装了WSA开头的socket函数,提供了socket通信更加简单的操作,是一个异步socket类 2.CSocket类 -继承自CAsyncSocket类,是一个同步socket类 3.使用MFC的socket类完成一个简单的文件传输的功能

Delphi线程类 DIY(把类指针作为参数传进去,就可以执行类里面的方法啦)

Delphi 封装了一个很强大的线程类 TThread, 我们也自己动手制作一个简单的线程类 首先Type一个类 [delphi] view plain copy type TwwThread = class constructor Create; overload; destructor Destroy; override; private m_hThread: THandle;     //线程 m_ThreadID : TThreadID; public procedure Execute

MFC的基类

CWnd 提供窗口处理的一个类,里面有HWND m_hWnd成员 CDC 绘图类,所有和绘图有关的操作封装在这个类,CClientDC, CWindowDC皆派生自它,里面有m_nHdc成员 MFC的基类,布布扣,bubuko.com

封装业务类

1.什么是业务类? 业务类:专门处理某项业务(事情) 2.业务类的作用? 把一些业务的业务逻辑封装起来,其它类需要处理这些业务的时候,直接调用业务类的方法就可以了 大大减少了其它类中的代码量,让代码看起来更整洁,可读性更好 3.业务类的规范 3.1 在类的上面,注明这个类的功能(作用) 让其它人一看到这个类就知道是干什么用的,减少沟通成本 1 // Created by XT on 16/7/31. 2 // Copyright © 2016年 XT. All rights reserved.

Delphi 实现多线程编程的线程类 TThread

http://blog.csdn.net/henreash/article/details/3183119 Delphi中有一个线程类TThread是用来实现多线程编程的,这个绝大多数Delphi书藉都有说到, 但基本上都是对TThread类的几个成员作一简单介绍,再说明一下Execute的实现和Synchronize的用法就完了. 然而这并不是多线程编程的全部,我写此文的目的在于对此作一个补充. 线程本质上是进程中一段并发运行的代码. 一个进程至少有一个线程,即所谓的主线程. 同时还可以有多个

转:学习笔记: Delphi之线程类TThread

学习笔记: Delphi之线程类TThread - 5207 - 博客园http://www.cnblogs.com/5207/p/4426074.html 新的公司接手的第一份工作就是一个多线程计算的小系统.也幸亏最近对线程有了一些学习,这次一接手就起到了作用.但是在实际的开发过程中还是发现了许多的问题,比如挂起与终止的概念都没有弄明白,导致浪费许多的时间. TThread-简单的开始 在Delphi的VCL中封装了一个TThread类用于多线程的开发,这样比较符合面向对象的思想,同时又可以提