终止线程的4种方式,java 线程终止
如何终止一个线程的运行
要终止线程的运行,可以使用以下方法:
1.线程函数返回(最好用这个方法)。
2.通过调用ExitThread函数,线程会自行取消(最好不要用这个方法)。
3.同一个进程或另一个进程中的线程调用TerminateThread函数(应避免使用此方法)。
4.ExitProcess和TerminateProcess函数也可以用来终止线程的运行(应该避免使用这种方法)。
下面将详细描述终止线程运行的方法:1-4,解释线程终止运行时会发生什么:5。
1.线程函数返回
线程应该总是以这样的方式设计,当你想让它们停止运行时,它们可以返回。这是确保正确清除所有线程资源的唯一方法。
如果线程可以返回,则可以确保:
(1)所有在线程函数中创建的C对象都会被它们的撤销函数正确撤销。
(2)操作系统将正确释放线程堆栈使用的内存。
(3)系统将线程的退出代码(维护在线程的内核对象中)设置为线程函数的返回值。
(4)系统将减少线程内核对象的使用计数。
2.ExitThread函数
您可以让线程调用ExitThread函数来强制线程停止运行:
功能原型:
VOID exit thread(DWORD dwExitCode);
该函数将终止线程,并使操作系统清除该线程使用的所有操作系统资源。但是,C资源(如C类对象)不会被撤销。为此,最好从thread函数返回,而不是调用ExitThread。
当然可以用ExitThread的dwExitThread参数告诉系统为什么要设置线程的退出代码。ExitThread函数不返回值,因为线程已经停止运行,无法执行更多代码。
请注意,终止线程的最佳方式是让其线程函数返回。但是,如果您使用本节描述的方法,您应该知道ExitThread函数是Windows用来撤消线程的函数。如果你写的是C/C代码,那就千万不要调用ExitThread。应该使用Visual C运行时库函数_endthreadex。如果你不用微软的Visual C编译器,你的编译器厂商有自己的ExitThread的替换函数。无论这个替代函数是什么,都必须使用。
3.终止线程功能
调用TerminateThread函数也可以终止线程的运行:
功能原型:
布尔终止线程(
处理高温线程,
DWORD dwExitCode);
与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(
处理高温线程,
PD word pdwExitCode);
退出代码的值在pdwExitCode指向的DWORD中返回。如果在调用GetExitCodeThread时线程还没有停止运行,那么函数将用STILL_ACTIVE标识符(定义为0x103)填充DWORD。如果函数运行成功,它将返回TRUE。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。