万丈高楼平地起之线程篇

来源:互联网 发布:阿里云机房测速 编辑:程序博客网 时间:2024/04/30 16:20

前言:

作为一名刚出道的学生,可能在工作中会遇到好多好奇的知识,而这些知识有没有开源,可能使用起来底气没有那么足。
其实 这些所有的已封装的东西,都是对最基础(底层)的函数库的调用与封装。自己动手实现对某个功能的封装,不仅可以
很好的了解到其内部实现的方式,同时也加深对知识的认知程度,还可以对以后的程序设计的模块化(面向对象的编程思想)
有所认识。

内容:

好了废话不多说了,直接上代码了(封装的线程)
头文件:
#ifndef _H_T_BASE_H_#define _H_T_BASE_H_#include<windows.h>class CTBase{public:typedef enum{TBRUNNING = 0, //不挂起TBSUSPEND = 4  // 挂起}CREATEFLAG;public:CTBase();virtual ~CTBase();public:bool TBCreateThread(CREATEFLAG createFlag);bool TBDestroyThread();bool TBBeginThread();bool TBEndThread();bool TBSuspendThread();bool TBResumeThread();void GetThreadID(unsigned &threadID);    void SetStop(bool bStop);    bool GetStop();private:static unsigned _stdcall TBTFunc(void *pThis);virtual bool TBRun() = 0;private:HANDLE hTHandle;unsigned uThreadID;    bool     m_bStop;};#endif

源文件:
#include "TBase.h"#include <process.h>CTBase::CTBase(){hTHandle = NULL;    m_bStop  = false;}CTBase::~CTBase(){}bool CTBase::TBCreateThread(CREATEFLAG createFlag){if(hTHandle != NULL)return false;hTHandle = (HANDLE)_beginthreadex(NULL,0,CTBase::TBTFunc,this,createFlag,&uThreadID);if(hTHandle == NULL)return false;return true;}bool CTBase::TBDestroyThread(){
<span style="white-space:pre"></span>CloseHandle(hTHandle);_endthreadex(0);return true;}bool CTBase::TBBeginThread(){return true;}bool CTBase::TBEndThread(){return true;}bool CTBase::TBSuspendThread(){unsigned long nResult = SuspendThread(hTHandle);if(nResult == -1)return false;return true;}bool CTBase::TBResumeThread(){unsigned long nResult = ResumeThread(hTHandle);if(nResult == -1)return false;return true;}unsigned _stdcall CTBase::TBTFunc(void *pThis){CTBase *pTBase = (CTBase*)(pThis);pTBase->TBBeginThread();    while(!pTBase->m_bStop)    {        pTBase->TBRun();    }pTBase->TBEndThread();return 0;}void CTBase::GetThreadID(unsigned &threadID){threadID = uThreadID;}void CTBase::SetStop( bool bStop ){    m_bStop = bStop;}bool CTBase::GetStop(){    return m_bStop;}


在封装过程中也遇到了好多问题,下面一一介绍下:
(1) 关于多线程的创建
创建方式有3中:
        1. CreateThread ()  函数 属于操作系统级别的(不提倡使用)
2. _beginthread () 和 _beginthreadex()  属于语言级别的 其内部会调用CreateThread 函数,但调用之前会做其他的额外工作
3.   AfxBeginThread() 该函数属于平台级别的(只限于Microsoft 提供的集成开发环境VS),其可以创建界面线程和工作线程两种。

终止线程的方法:
1. 最好的方法是让线程自己执行玩,自动退出
2.ExitThread(HANDLE) 退出
3.TerminateThread(HANDLE)强制退出线程
4.通过调用终止进程,间接地终止线程
5.对于_beginthread() 和_beginthreadex() 创建的线程,应使用配套的函数去终止线程,其函数为
   _endthread() 和 _endthreadex()

在退出线程时,要手动去释放掉一些资源比如 线程句柄。
下面是一个关于线程退出时,调用不同函数所做的事情:
点击打开链接

关于界面线程:
界面线程是MFC中一个特殊的线程,其有自己的消息循环机制,而工作线程只是关心要做的事情。

 (2)关于虚函数
在上述类中,使用到了一个关键字(virtual) ,该关键字是虚函数的标志。
上述的虚函数属于纯虚函数,引起满足纯虚函数的定义  

virtual bool TBRun() = 0;
含有纯虚函数的类,是不能够声明类对象的

虚函数是c++动态链编的一中实现方式(重写),
其静态链编的方式是 函数的重载   (重载)。
这两种方式都是c++实现多态的方式,
只不过函数重载在编译时就已经确定调用那个函数,
而函数的重写,是在程序运行时,在确定调用那个函数

其实函数的重写,类似于一种私人订制,他提供给你一个画板,如果你想改变一下画板的内容,就自己动手,
画上自己想画的内容,在执行时,就按照你的意愿进行。

一个大神的作品,关于虚函数在每个类对象中的内存存储及存储方式:
点击打开链接

0 0