终止线程的4种方式,java 线程终止

  终止线程的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的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: