《Windows via C/C++》学习笔记 —— 线程基础

徘徊边缘 提交于 2020-03-15 19:08:27

  每个进程都有一个主线程。每个线程都包含2个部分:

1、一个内核对象,操作用此来管理线程,里面包含了线程的状态;

2、一个线程堆栈,用来维护所有的函数参数和局部变量。

 

  启动线程,需要提供一个线程入口函数,该函数原形必须为如下形式:

DWORD WINAPI ThreadFunc(PVOID pvParam)
{
     DWORD dwRet 
= 0;
     
return dwRet;
}

 

  在这个函数里,你的线程执行相关任务,当该函数返回时,线程便停止了运行。线程堆栈也被清除,线程内核对象的引用计数减1。

 

  你可以使用CreateThread函数创建一个线程,该函数返回一个线程内核对象句柄。

  结束一个线程有4中方法:

1、线程函数返回

2、线程自己调用ExitThread函数终止自己运行

3、本进程内的其他线程或该线程自己调用TerminateThread函数指定终止一个进程

4、包含该线程的进程终止

  应该尽量使用第1种方法,确保线程终止的时候所有资源可以被系统正确地回收。

 

  线程内核对象中维护了一些数据结构,包括一个反应该线程最近运行情况的上下文内容“CONTEXT”,里面有一些“CPU的寄存器信息”,主要包括一个SP和IP,分别保存了线程堆栈中的入口函数地址和NTDLL.dll中的RtlUserThreadStart函数地址,该函数用来执行线程代码,并试图结束线程和处理一些异常。

  数据结构中还包括一些属性信息:引用计数,挂起计数,退出代码(在运行的时候为STILL_ACITVE),受信状态(初始为FALSE)。

 

  C/C++运行期函数中提供了2个创建线程的函数,使用这两个函数需要包含头文件“Process.h”,这两个函数是:_beginthread,_beginthreadex,与这两个函数配套使用的结束线程的2个函数是:_endthread,_endthreadex,可以在线程内部使用end函数结束线程,但是不推荐这么做,让线程函数自动返回更好。

  _beginthread函数功能比较少,推荐使用_beginthreadex函数,其参数和返回值CreateThread函数本质上是相同的,只是顺序和类型不同,需要强制转换,_beginthreadex函数在内部会调用CreateThread函数,但是比CreateThread安全而且可靠。

  另外,尽量使用_beginthreadex函数而不要使用CreateThread函数,貌似后者可能容易引起资源的泄漏而且不是非常可靠(个人理解)。

 

  要取得本进程和本线程对应的句柄,可以使用GetCurrentProcess和GetCurrentThread函数。但是需要注意,这两个函数只返回伪句柄,也就是说这个返回值表明的意思就是“当前句柄”,而不代表“T1的句柄”(假设T1为当前线程)。当把这个伪句柄传递给其他进程或线程的时候,在其他进程和线程中也仅仅把它作为“当前句柄”来处理,假设线程T1调用GetCurrentThread得到一个伪句柄H,把它传给线程T2,T2就认为这个H也是“当前句柄”,也就是T2的线程对象句柄,而不是T1的了。

  要将伪句柄转换为真实的句柄,可以使用复制句柄函数——DuplicateHandle函数。该函数在本书第三章有介绍,这里就不再说了。

 

  第六章细节比较多,看过之后只能记个大概,很多就记了一个结论,够用就好吧,呵呵!

  

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!