在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
每个进程都有一个主线程。每个线程都包含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函数。该函数在本书第三章有介绍,这里就不再说了。
第六章细节比较多,看过之后只能记个大概,很多就记了一个结论,够用就好吧,呵呵!
|
2023-10-27
2022-08-15
2022-08-17
2022-09-23
2022-08-13
请发表评论