万丈高楼平地起之线程篇

前言:

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

内容:

好了废话不多说了,直接上代码了(封装的线程)
头文件:
#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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值