本文是关于如何终止C/C中运行的线程的详细分析和介绍,供大家参考。
想要终止线程的运行,可以使用以下方法: 1.线程函数返回(最好用这个方法)。2.通过调用ExitThread函数,线程会自行取消(最好不要用这个方法)。3.同一个进程或另一个进程中的线程调用TerminateThread函数(应避免使用此方法)。4.ExitProcess和TerminateProcess函数也可以用来终止线程的运行(应该避免使用这种方法)。
下面将详细描述终止线程运行的方法:1-4,解释线程终止运行时会发生什么:5。
1、线程函数返回 线程应该总是以这样一种方式设计,当您希望它们停止运行时,它们可以返回。这是确保正确清除所有线程资源的唯一方法。如果线程可以返回,那么可以保证以下几点:(1)所有在线程函数中创建的C对象都会被它们的撤销函数正确撤销。(2)操作系统将正确释放线程堆栈使用的内存。(3)系统将线程的退出代码(维护在线程的内核对象中)设置为线程函数的返回值。(4)系统将减少线程内核对象的使用计数。
2、ExitThread函数 可以让线程调用ExitThread函数强制线程停止运行:函数原型:void退出线程(dword dwexit代码);该函数将终止线程,并使操作系统清除该线程使用的所有操作系统资源。但是,C资源(如C类对象)不会被撤销。为此,最好从thread函数返回,而不是调用ExitThread。当然可以用ExitThread的dwExitThread参数告诉系统为什么要设置线程的退出代码。ExitThread函数不返回值,因为线程已经停止运行,无法执行更多代码。注意终止线程运行的最佳方法是让它的线程函数返回。但是,如果使用本节介绍的方法,应该知道ExitThread函数是Windows用来撤销线程的函数。如果你写的是C/C代码,那就千万不要调用ExitThread。应该使用Visual C运行时库函数_endthreadex。如果你不用微软的Visual C编译器,你的编译器厂商有自己的ExitThread的替换函数。无论这个替代函数是什么,都必须使用。
3、TerminateThread函数 调用TerminateThread函数也可以终止线程的运行:函数原型:复制代码如下:Bool termin ate Thread(handle hthread,dword dwexit代码);与ExitThread不同,ExitThread总是取消调用线程,而TerminateThread可以取消任何线程。HTREAD参数用于标识终止线程的句柄。当线程终止时,它的退出代码变成您作为dwExitCode参数传递的值。同时,线程的内核对象的使用计数也递减。注意TerminateThread函数是异步运行的函数,也就是告诉系统你想让线程停止运行。但是,当函数返回时,不能保证线程会被取消。如果您需要确定线程已经终止,您必须调用WaitForSingleObject或类似的函数来传递线程的句柄。设计良好的应用程序从不使用这个函数,因为已经被终止的线程无法接收到它已经被撤销的通知。线程无法正确清除,也无法防止自己被撤销。注意当使用返回或调用ExitThread的方法撤消线程时,该线程的内存堆栈也被撤消。但是,如果使用了TerminateThread,在拥有该线程的进程终止运行之前,系统不会撤消该线程的堆栈。微软故意用这种方法来实现TerminateThread。如果仍在执行的其他线程引用被强制撤销的线程堆栈上的值,则其他线程将发生访问冲突。如果被取消线程的堆栈留在内存中,那么其他线程可以继续正常运行。此外,DLL通常会在线程终止运行时收到通知。如果使用TerminateThread强制线程终止,DLL将不会收到通知,这可能会阻止正确的清理。
4、在进程终止运行时撤消线程 ExitProcess和TerminateProcess函数也可用于终止线程的运行。不同的是,这些线程会导致已终止进程中的所有线程终止。此外,由于整个进程已经关闭,因此该进程使用的所有资源肯定都已被清除。这当然包括所有线程的堆栈。这两个函数会导致进程中剩余的线程被强制取消,就像从每个剩余的线程调用TerminateThread一样。显然,这意味着正确的应用程序清理没有发生,即没有调用C对象撤销函数,数据没有转移到磁盘,等等。
5、线程终止运行时发生的操作 当线程终止运行时,会发生下列操作: (1)释放线程拥有的所有用户对象。在Windows中,大多数对象由包含创建它们的线程的进程所拥有。但是一个线程有两个用户对象,即window和hook。当线程停止运行时,系统会自动取消任何窗口,并卸载线程创建或安装的任何钩子。其他对象只有在拥有该线程的进程停止运行时才会被撤销。(2)线程的退出代码由STILL_ACTIVE改为传递给ExitThread或TerminateThread的代码。(3)通知线程内核对象的状态。(4)如果线程是进程中的最后一个活动线程,系统也将该进程视为终止。(5)线程内核对象的使用计数减1。当一个线程终止运行时,内核对象不会被自动释放,直到其关联的线程内核对象的所有未完成的引用都被关闭。一旦线程不再运行,系统中就没有其他线程可以处理该线程的句柄。但是其他线程可以调用GetExitcodeThread来检查hThread标识的线程是否已经停止运行。如果已经停止运行,确定其退出代码:函数原型:复制代码如下:Bool GetExitCodeThread(Handle Hthread,PDWord PDW退出代码);退出代码的值在pdwExitCode指向的DWORD中返回。如果在调用GetExitCodeThread时线程还没有停止运行,那么函数将用STILL_ACTIVE标识符(定义为0x103)填充DWORD。如果函数运行成功,它将返回TRUE。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。