热门标签 | HotTags
当前位置:  开发笔记 > 开发工具 > 正文

解析C/C++中如何终止线程的运行

本篇文章是对CC++中如何终止线程运行的方法进行了详细的分析介绍,需要的朋友参考下

想要终止线程的运行,可以使用以下方法:
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。


推荐阅读
  • 本文探讨了Lua中元表和元方法的使用,通过具体的代码示例展示了如何利用这些特性来实现类似C语言中的运算符重载功能。 ... [详细]
  • Minetest 0.4.9 开源游戏在 Ubuntu 下通过 PPA 安装指南
    本文介绍了如何在 Ubuntu 系统上安装最新版本的 Minetest 0.4.9,包括添加 PPA、更新软件包列表以及安装过程,适合所有 Ubuntu 及其衍生系统的用户。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置单节点的Redis服务,包括下载、解压、编译安装以及启动服务的具体步骤。 ... [详细]
  • 去控件化在线文档处理,推动高效信创办公环境
    探讨在线文档处理去控件化的趋势及其对构建高效信创办公生态的影响。 ... [详细]
  • Mac环境下Java与Ant自动化构建环境搭建指南
    本文详细介绍了如何在Mac操作系统上为测试工程师搭建Java和Ant开发环境,包括环境变量配置等关键步骤。 ... [详细]
  • 本周六上午11点左右到达公司,回顾了一周的行业动态并完成了昨日的任务。下午主要解决了Axis2缓存问题以及DBS和KMS的相关技术难题。由于服务替换导致平台访问错误,经过多方查找未能解决,最终决定暂时搁置。此外,还分享了与朋友之间的沟通障碍及个人成长的思考。 ... [详细]
  • 本文介绍了如何使用Windows自带的命令行工具来终止大多数进程,包括ntsd和tskill等高级命令的具体使用方法。 ... [详细]
  • Pandas中使用sort_values方法进行数据排序
    本文介绍了如何利用Python的Pandas库中的sort_values方法对DataFrame对象进行排序。首先通过Numpy库生成随机数据,然后详细解释了DataFrame的创建过程及其参数,并重点探讨了sort_values方法的使用技巧。 ... [详细]
  • 迷宫问题_____________________________________________问题描述:给定一个二维数组如下所示,数值1位墙壁,0 ... [详细]
  • Python与Java在Appium中的应用:混合APP自动化测试方法详解
    本文详细探讨了如何使用Python和Java语言结合Appium框架进行混合APP的自动化测试,特别针对面试中常见的问题进行了整理和解答。 ... [详细]
  • 在使用Nacos过程中,突然遇到了‘Can’t find dependent libraries’的错误。尽管安装了C++组件,但问题依旧存在。经过一番排查,发现是由于之前修改Windows设置以解决《生化奇兵-无限》游戏存档丢失问题所导致。 ... [详细]
  • 13、单向链表
    头文件:LinkList.hLinkList.cmain.cVS2 ... [详细]
  • UVA 401 - 镜像回文字符串
    本题探讨了如何判断一个字符串是否为普通回文、镜像回文或两者都不是。通过特定的字符映射表来实现字符串的镜像转换,并根据转换后的结果进行分类。 ... [详细]
  • 抽象工厂模式 c++
    抽象工厂模式包含如下角色:AbstractFactory:抽象工厂ConcreteFactory:具体工厂AbstractProduct:抽象产品Product:具体产品https ... [详细]
  • 笔记本喇叭图标不见了 ... [详细]
author-avatar
yema狂想曲
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有