如何终止线程的运行(C/C++)
想要终止线程的运行,可以使用以下方法:
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。
- 浏览: 2648756 次
- 性别:
- 来自: 宜昌
文章分类
- 全部博客 (616)
- C/C++ (117)
- Java (30)
- UnrealEngine (185)
- Unity3D (10)
- CryEngine (1)
- 3D (18)
- JVM (7)
- Build (34)
- Android (23)
- Windows (39)
- Linux (24)
- DB (17)
- Tools (14)
- VersionControl (23)
- Node.js (9)
- DeveEnv (2)
- VisualStudio (13)
- WindowsPhone (2)
- Socket (11)
- Network (15)
- LoadRunner (1)
- Game (10)
- Eclipse (1)
- Optimization (4)
- 下载资源 (1)
- 网络设置 (4)
- Experience (1)
- Store (8)
- Cache (1)
- OpenSource (5)
- Thread (2)
- JNI (1)
- Benchmark (12)
- Python (1)
- Algorithm (14)
- FreeBSD (3)
- Postgresql (6)
- JSP (3)
- Lua (3)
- iOS (1)
- Web (4)
- Golang (5)
- Shader (2)
- Dlang (2)
- 音乐 (1)
- 非技术 (3)
- Math (6)
最新评论
-
aigo:
senlin305 写道为了不至于误导后续来解决问题的人,专门 ...
gitblit无法安装windows服务或者启动服务失败:Failed creating java -
vhly:
录了一套关于MediaPlayer的视频,有播放控制、播放列表 ...
[UE4]如何播放视频文件(media) -
vhly:
制作了一套关于 UE4 Spline 的基础视频,包含 蓝图 ...
[UE4]蓝图-SplineMeshComponent用法 -
senlin305:
为了不至于误导后续来解决问题的人,专门弄个帐号来回复一下。出现 ...
gitblit无法安装windows服务或者启动服务失败:Failed creating java -
^=^:
请问博主试过这个方法吗?有效吗?
windows 10 更新失败:We couldn't complete the updates, undoing changes
发表评论
-
[C++]比memcpy快50%的FastMemcpy
2016-05-26 13:03 4271云风老大用汇编实现的一个高效memcpy,号称比传统 ... -
比memcpy更快的内存拷贝:用赋值代替循环拷贝
2016-05-21 12:40 13088原文是出自百度空间,百度空间早已关闭,所以原文出处无法查询 ... -
C++ 实现把非静态成员函数作为回调函数(非static)
2016-05-20 12:33 3084C++ Thunk方式: https://blog.tw ... -
[C++]MFC使用CFile读写Unicode字符集文件(文件头缺失导致乱码)
2016-05-19 21:19 5732原文:http://blog.csdn.net/augus ... -
C++ fopen、CFile如何以UTF-8编码格式读写文件
2016-05-13 22:17 17047How to write UTF-8 file wi ... -
std::shared_mutex和std::mutex的性能对比(banchmark)
2016-05-06 23:39 6770原文作者:@玄冬Wong 转载请注明原文出处:http: ... -
[VC++]release版本编译输出的文件比debug版本体积大的原因
2016-05-01 18:49 2004原因: 多半是因为release模式下开启了全程序 ... -
[C++]如何判断exe和dll文件是debug还是release编译生成的
2016-05-01 15:43 4497用depends工具查看: debug模式的dll和ex ... -
[cmake]target_link_libraries参数:PRIVATE、PUBLIC、INTERFACE三者区别
2016-04-30 16:14 7379原文: CMake target_link_lib ... -
C++11的std::array初始化问题
2016-04-26 23:04 2171std::array中的元素必须在编译期间就要初始化 ... -
vs2010中的stdext::hash_map在vs2015下的问题
2016-04-25 17:21 2959vs2010中的hash_map调用方式: 需要头文件& ... -
[C++]VS2015 update2的安全检测:decorated name length exceeded, name was truncated
2016-04-25 16:54 2152vs2015 update 2对安全检测越来越严格了,以前 ... -
[C++11]如何让std::condition_variable的内部类参数可以被修改(默认是const)
2016-04-22 13:18 1002使用std::condition_variable时出 ... -
[C++11]std::mutex和std::atomic的性能测试对比(benchmark)
2016-04-21 12:28 4761key word:std::mutex、std::atom ... -
多个生产者多个消费者:boost::lockfree::queue和std::mutex的性能对比(benchmark)
2016-04-20 21:45 4621原文作者:@玄冬Wong key word:Non-bl ... -
[C++]boost::unique_lock与boost::lock_guard区别
2016-04-19 07:20 2319关键字:thead、多线程、锁 lock_guar ... -
[C++]阻塞和非阻塞的队列的性能对比(Non-BlockingQueue&BlockingQueue benchmark)
2016-04-19 11:32 9306关键字:阻塞队列、非阻塞队列、性能对比、Non-Block ... -
[C++]std::atomic_flag的初始化问题
2016-04-18 14:04 2844如果定义了 std::atomic_flag 类型变量,则初 ... -
[C++]boost提供的几种lock-free方案以及std::atomic实现无锁队列
2016-04-18 10:48 23894boost方案 boost提供了三种无锁方案 boos ... -
[C++11]std::atomic:store和load的示例(example)
2016-04-18 00:32 3390原文: std::memory_order http: ...
相关推荐
VC++提供了多种方式实现线程间的通信,如消息队列、共享内存、管道、线程间信号量等。其中,Windows的消息队列机制是常见的通信方式,通过`PostMessage`和`GetMessage`函数可以在不同线程间传递消息。 5. **线程...
在编程领域,多线程是一种重要的并发执行方式,特别是在C++这样的系统级编程语言中,多线程技术能够显著提高程序的效率和响应性。在Windows环境下,Microsoft Visual Studio(如VS2005)提供了丰富的支持来创建和...
最后,注意线程安全的编程习惯,避免全局变量,尽量减少共享数据,合理使用同步机制,以及正确地管理和终止线程,这些都是保证多线程程序正确性和性能的重要因素。 通过深入学习和实践本资料中的示例,你将能够熟练...
提供一套在VC++开发中需要使用到的创建线程和终止线程方法。
包里面有10个文件,分别是:如何安全终止线程;如何创建UI线程;如何创建Worker线程;如何等待线程结束;如何挂起和恢复线程;如何获得线程的退出码;如何使用互斥量;如何使用临界区;如何使用事件;如何使用信号量
在Windows环境下,Visual C++(简称VC++)提供了一种强大的工具集,用于开发多线程应用程序。多线程编程是现代计算机系统中实现并发执行任务的重要技术,它允许程序同时执行多个独立的执行路径,从而提高程序的效率...
"VC++多线程 垃圾清理工具"是利用Microsoft Visual C++(VC++)环境,结合MFC(Microsoft Foundation Classes)库实现的一个实例,旨在通过多线程技术来优化系统垃圾清理的过程。这个工具不仅提供了学习多线程编程的...
5. **线程结束与资源释放**:当所有线程完成下载任务后,应正确终止线程并释放资源。对于WinAPI创建的线程,可以调用`TerminateThread`(需谨慎使用),对于`std::thread`,可以调用`join`或`detach`方法。别忘了...
标题中提到的"VC++多线程编程"涉及到VC++,即...文中给出了创建线程、暂停线程、终止线程的API函数示例,展示了如何在对话框程序中集成多线程逻辑。这些都是在学习和进行VC++多线程编程时应该掌握的基础知识和技能。
在VC++中,创建线程主要有两种方法:使用Windows API函数和使用C++标准库中的`std::thread`。 1. **使用Windows API函数创建线程** 在Windows API中,可以使用`CreateThread`函数来创建新的线程。首先,你需要...
4. **如何安全终止线程** 终止线程并不是一件简单的事情,因为可能在任何时候,线程可能正在执行关键操作。使用`TerminateThread`函数可以强制结束线程,但这是不推荐的,因为它可能导致资源泄漏和未定义的行为。...
### VC++多线程编程方法 #### 一、引言 多线程编程在现代软件开发...综上所述,多线程编程是一种强大的技术手段,但同时也伴随着许多挑战。掌握正确的设计原则和编程技巧对于构建高性能、可靠的多线程应用至关重要。
- `TerminateThread`强制终止线程,但不建议常规使用,因为它可能导致资源泄漏或不稳定状态。 - `PostThreadMessage`用于向线程发送消息,适用于线程间的通信。 ### 示例代码解析 以下是一个基于Win32 API的多线程...
4. **资源管理**:在所有线程完成任务后,应正确地终止和清理它们。这可以通过设置退出标志、调用`ExitThread`或`CloseHandle`来完成。 5. **错误处理**:多线程编程中,错误处理特别重要,因为线程间的异常处理和...
在VC++中进行线程操作时,了解如何正确创建和终止线程是非常重要的。通过上述方法,我们可以有效地管理和控制线程,从而避免程序中的潜在错误。在实际编程过程中,建议优先考虑使用安全标志的方式,因为它提供了更好...
串口通信,也称为串行通信,是计算机通信的一种基本方式。它允许设备通过串行数据链路进行信息交换。在VC++中实现串口通信,通常涉及Windows API中的`CreateFile`、`SetCommState`、`ReadFile`和`WriteFile`等函数。...