想要终止线程的运行,可以使用以下方法:

1、线程函数返回(最好使用该方法)。
2、通过调用ExitThread函数,线程将自行撤消(最好不使用该方法)。
3、同一个进程或另一个进程中的线程调用TerminateThread函数(应避免使用该方法)。
4、ExitProcess和TerminateProcess函数也可以用来终止线程的运行(应避免使用该方法)。

下面将详细介绍终止线程运行的方法:1-4,并说明线程终止运行时会出现何种情况:5。

1、线程函数返回

始终都应该将线程设计成这样的形式,即当想要线程终止运行时,它们就能够返回。这是确保所有线程资源被正确地清除的唯一办法。
如果线程能够返回,就可以确保下列事项的实现:
(1)在线程函数中创建的所有C++对象均将通过它们的撤消函数正确地撤消。
(2)操作系统将正确地释放线程堆栈使用的内存。
(3)系统将线程的退出代码(在线程的内核对象中维护)设置为线程函数的返回值。
(4)系统将递减线程内核对象的使用计数。

2、ExitThread函数

可以让线程调用ExitThread函数,以便强制线程终止运行:
函数原型:

VOID ExitThread(DWORD dwExitCode);

该函数将终止线程的运行,并导致操作系统清除该线程使用的所有操作系统资源。但是,C++ 资源(如C++ 类对象)将不被撤消。由于这个原因,最好从线程函数返回,而不是通过调用ExitThread来返回。
当然,可以使用ExitThread的dwExitThread参数告诉系统将线程的退出代码设置为什么。ExitThread函数并不返回任何值,因为线程已经终止运行,不能执行更多的代码。
注意终止线程运行的最佳方法是让它的线程函数返回。但是,如果使用本节介绍的方法,应该知道ExitThread函数是Windows用来撤消线程的函数。如果编写C/C++ 代码,那么决不应该调用ExitThread。应该使用Visual C++ 运行期库函数_endthreadex。如果不使用Microsoft的Visual C++编译器,你的编译器供应商有它自己的ExitThread的替代函数。不管这个替代函数是什么,都必须使用。

3、TerminateThread函数

调用TerminateThread函数也能够终止线程的运行:
函数原型:

BOOL TerminateThread( HANDLE hThread, DWORD dwExitCode);

与ExitThread不同,ExitThread总是撤消调用的线程,而TerminateThread能够撤消任何线程。hThread参数用于标识被终止运行的线程的句柄。当线程终止运行时,它的退出代码成为你作为dwExitCode参数传递的值。同时,线程的内核对象的使用计数也被递减。

注意TerminateThread函数是异步运行的函数,也就是说,它告诉系统你想要线程终止运行,但是,当函数返回时,不能保证线程被撤消。如果需要确切地知道该线程已经终止运行,必须调用WaitForSingleObject或者类似的函数,传递线程的句柄。
设计良好的应用程序从来不使用这个函数,因为被终止运行的线程收不到它被撤消的通知。线程不能正确地清除,并且不能防止自己被撤消。

注意当使用返回或调用ExitThread的方法撤消线程时,该线程的内存堆栈也被撤消。但是,如果使用TerminateThread,那么在拥有线程的进程终止运行之前,系统不撤消该线程的堆栈。Microsoft故意用这种方法来实现TerminateThread。如果其他仍然正在执行的线程要引用强制撤消的线程堆栈上的值,那么其他的线程就会出现访问违规的问题。如果将已经撤消的线程的堆栈留在内存中,那么其他线程就可以继续很好地运行。

此外,当线程终止运行时, DLL通常接收通知。如果使用TerminateThread 强迫线程终止,DLL就不接收通知,这能阻止适当的清除。

4、在进程终止运行时撤消线程

ExitProcess和TerminateProcess函数也可以用来终止线程的运行。差别在于这些线程将会使终止运行的进程中的所有线程全部终止运行。另外,由于整个进程已经被关闭,进程使用的所有资源肯定已被清除。这当然包括所有线程的堆栈。这两个函数会导致进程中的剩余线程被强制撤消,就像从每个剩余的线程调用TerminateThread一样。显然,这意味着正确的应用程序清除没有发生,即C++对象撤消函数没有被调用,数据没有转至磁盘等等。

5、线程终止运行时发生的操作

当线程终止运行时,会发生下列操作:
(1)线程拥有的所有用户对象均被释放。在Windows中,大多数对象是由包含创建这些对象的线程的进程拥有的。但是一个线程拥有两个用户对象,即窗口和挂钩。当线程终止运行时,系统会自动撤消任何窗口,并且卸载线程创建的或安装的任何挂钩。其他对象只有在拥有线程的进程终止运行时才被撤消。
(2)线程的退出代码从STILL_ACTIVE改为传递给ExitThread或TerminateThread的代码。
(3)线程内核对象的状态变为已通知。
(4)如果线程是进程中最后一个活动线程,系统也将进程视为已经终止运行。
(5)线程内核对象的使用计数递减1。
当一个线程终止运行时,在与它相关联的线程内核对象的所有未结束的引用关闭之前,该内核对象不会自动被释放。

一旦线程不再运行,系统中就没有别的线程能够处理该线程的句柄。然而别的线程可以调用GetExitcodeThread来检查由hThread标识的线程是否已经终止运行。如果它已经终止运行,则确定它的退出代码:

函数原型:

BOOL GetExitCodeThread( HANDLE hThread, PDWORD pdwExitCode);

退出代码的值在pdwExitCode指向的DWORD中返回。如果调用GetExitCodeThread时线程尚未终止运行,该函数就用STILL_ACTIVE标识符(定义为0x103)填入DWORD。如果该函数运行成功,便返回TRUE。

更多参考

转载于:https://www.cnblogs.com/ZY-Dream/p/10147544.html

如何终止线程的运行(C/C++)相关推荐

  1. java线程中断和终止线程运行

    ava中启动一个线程很容易,通常情况下我们都是等到任务运行结束后让线程自行停止.但有时需要在任务正在运行时取消他们,使得线程快速结束.对此Java并没有提供任何机制.但是我们可以通过Java提供的线程 ...

  2. Java的知识点30——线程的优先级、终止线程的典型方式、获取线程基本信息的方法

    线程的优先级  1-10 1. NORM_PRIORITY  5 默认  2. MIN_PRIORITY  1  3. MAX_PRIORITY  10 注意:优先级低只是意味着获得调度的概率低.并不 ...

  3. 震惊!这样终止线程,竟然会导致服务宕机?

    来自:Java中文社群 在开始之前,我们先来看以下代码会有什么问题? public class ThreadStopExample {public static void main(String[] ...

  4. 详解java中Thread类,线程和进程的基本区别,多线程的好处,线程的五个生命周期,主线程和IDEA创建的Monitor Ctrl-Break守护线程;优雅地终止线程。死锁的产生

    线程:CPU调度的最小单位:线程共享堆内存和方法区,但各自享有栈空间.进程:CPU分配资源的最小单位. 为什么需要多线程:①避免其中一个模块阻塞造成系统假死:②程序异步处理(交替执行),提高程序执行效 ...

  5. pyqt stop停止线程_面试官:如何终止线程?有几种方式?

    在 Java 中有以下 3 种方法可以终止正在运行的线程: 使用退出标志,使线程正常退出,也就是当 run() 方法完成后线程终止: 使用 stop() 方法强行终止线程,但是不推荐使用这个方法,因为 ...

  6. 线程的状态转换、sleep()、wait()、yeild()、终止线程的方法、线程之间的协作(join()、wait() notify() notifyAll()、await() signal() )

    1.线程的状态转换 1.1 新建(New) 创建后尚未启动 1.2 可运行(Runnable) 可能正在运行,也可能正在等待 CPU 时间片. 包含了操作系统线程状态中的 Running 和 Read ...

  7. android 如何终止线程

    今天,简单讲讲如何终止线程. Android终止线程的方法 线程对象属于一次性消耗品,一般线程执行完run方法之后,线程就正常结束了,线程结束之后就报废了,不能再次start,只能新建一个线程对象.但 ...

  8. java终止线程的三种方法

    有三种方法可以使终止线程. 1.  使用退出标志,使线程正常退出,也就是当run方法完成后线程终止. 2.  使用stop方法强行终止线程(这个方法不推荐使用,因为stop和suspend.resum ...

  9. MFC线程创建运行关闭的问题

    最近,由于论文的需求,要用到Windows下的多线程.考虑到界面用MFC写 了,于是上网搜了下MFC下的多线程怎样搞,都说用AfxBeginThread来日比较好.哥向来比较浮躁,先搜搜有没相关代码, ...

  10. C# 使用 CancellationTokenSource 终止线程

    我们在多线程中通常使用一个bool IsExit类似的代码来控制是否线程的运行与终止,其实使用CancellationTokenSource来进行控制更为好用,下面我们将介绍CancellationT ...

最新文章

  1. 导购网站 服务器,导购网站云服务器配置
  2. php auth_http,php auth_http类库进行身份效验
  3. ESP32­-PICO-­D4的使用
  4. P2181 对角线(python3实现)
  5. 140_Power BIPower Pivot之降维展示同类型比较
  6. 天地图给一个区域添加标题_一个小罐子就能做腌酸菜,7天就能吃,无任何添加,吃着更放心...
  7. 基于JAVA+JSP+MYSQL的小说网站阅读管理系统
  8. spring对redis的操作
  9. AngularJS学习之旅—AngularJS 事件(十四)
  10. RHEL7.X安装12.2RAC时root.sh错误CLSRSC-400的解决方案
  11. shell 命令管理tomcat
  12. 集成ahci驱动的xp系统_IDE转AHCI模式 for win7+SSD
  13. c语言程序流程图怎么写,C语言课程设计————写下流程图! 谢谢
  14. StringUtil.isNotEmpty
  15. 站群软件-免费站群软件
  16. python爬取网页数据总结_python之爬取网页数据总结(一)
  17. linux idle是什么进程,Linux idle基础
  18. 计算机三维设计ppt,1 三维建模技术发展史.ppt
  19. Shell脚本编程基础 三 使用结构化命令
  20. Vue 2 即将成为过去

热门文章

  1. tomcat内存溢出解决方案_JVM了解以下?JVM系列~内存区域与内存溢出异常
  2. 【渝粤教育】国家开放大学2018年秋季 0727-22T思想道德修养与法律基础 参考试题
  3. 【渝粤题库】陕西师范大学200021现代汉语 作业(高起本、高起专)
  4. 【渝粤教育】电大中专公共基础课程 (2)作业 题库
  5. Soft Value function基础和Soft Q Learning中Policy Improvement 证明
  6. 将自己电脑的SSH key添加到GitHub上
  7. 【ABAP系列】SAP ABAP 总结常用术语简称解析
  8. python自动华 (十二)
  9. 【转】char,wchar_t,WCHAR,TCHAR,ACHAR的区别
  10. win10安装kali组双系统