C++系列 --- 线程内核对象

一、线程内核对象

线程内核对象就是一个包含了线程状态信息的数据结构。每次对CreateThread函数的成功调用,系统都会在内部为新的线程分配一个内核对象。系统提供的管理线程的函数就是依靠访问线程内核对象来管理实现的。

线程内核对象结构

 线程创建内核对象时,系统对它的各个成员进行初始化

1> 线程上下文句柄

每个线程都有自己的一组CPU寄存器,成为线程的上下文。这组寄存器的值保存在一个CONTEXT结构里,反映了该线程上次运行时CPU寄存器的状态。

2> 使用技术Usage Count

该成员记录线程内核对象的使用次数。使用技术初始状态为2,创建一个线程时,因为CreateThread函数返回了线程内核对象的句柄,相当于打开一次,就促使Usage Count值加1。如果调用OpenThread函数,会再加1。

因此在使用完他们的句柄之后,一定要调用CloseHandle函数进行关闭。使Usage Count值减1.

如果在刚创建线程时调用CloseHandle函数关闭CreateThread函数返回的句柄,Usage Count值减为1,但线程没有被终止。线程结束要关闭句柄,不然内存泄漏。

3> 暂停次数 Suspend Count

该成员用于指明线程的暂停计数。

DWORD ResumeThread(HANDLE hThread); // 唤醒挂起线程

DWORD SuspendThread(HANDLE hThread); // 挂起线程

上面两个函数用于减少或增加Suspend Count。

在相同优先级下,当Suspend Count变为0时,系统可以调度该线程。

4> 退出代码 Exit Code 

Exit Code指定线程的退出代码,也可以说是线程函数的返回值。在线程运行期间,线程函数没有返回,值为STILL_ACTIVE。当线程结束后,系统自动将ExitCode设为线程函数的返回值。可以用GetExitCodeThread函数得到线程的退出代码。

5> 是否受信 Signaled

Signaled指示了线程对象是否为受信状态。运行期间FALSE,即未受信,线程结束后,系统将其置为TRUE,针对此对象的等待函数(如WaitForSingleObject)就会返回。

二、线程的终止

线程正常终止时,会发生以下时间:

在线程函数中创建的所有C++对象将通过他们各自的析构函数被正确的销毁。

该线程使用的堆栈被释放。

系统将线程内核对象中的ExitCode的值由STILL_ACTIVE设置为线程函数返回的值。

 系统将递减线程内核对象中Usage Count的值。

线程终止的四种方法

1、线程函数自然退出。

2、使用ExitThread函数来终止线程。

3、使用TeriminateThread函数在一个线程中强制终止另一个线程的运行。

3、使用ExitProcess函数结束进程。

线程自然退出这种情况时最安全的,但是其他三种方式会存在一个问题,ExitThread、TeriminateThread、ExitProcess为C风格的Win32函数,不会调用C++的运行时,即在释放资源的时候,析构函数不会被执行,具体实例如下:

示例

#include <iostream>
#include <Windows.h>
using namespace std;

class CMyObj
{
public:
	CMyObj()
	{
		printf("构造函数!\n");
	}

	~CMyObj()
	{
		printf("析构函数!\n");
	}
};

int main()
{
	CMyObj obj;

	system("pause");
	return 0;

}

 正常运行结果

在main函数中添加ExitThread()函数,则会出现问题,即析构函数不会被执行!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值