C/C++中退出线程的四种解决方法_C 语言

退出线程可以有四种方法:

1.线程函数的return返回(最好这样):
其中用线程函数的return返回, 而终止线程是最安全的, 在线程函数return返回后, 会清理函数内申请的类对象, 即调用这些对象的析构函数. 然后会自动调用 _endthreadex()函数来清理 _beginthreadex(...)函数申请的资源(主要是创建的tiddata对象).

2.调用 _endthreadex()函数 或 ExitThread()函数(最好不要):
如果使用这两种方法退出线程, 则不会执行线程函数的return语句, 所以就不会调用线程函数作用域内申请的类对象的析构函数, 会造成内存泄露.

剩下两种是在程序设计中一定要避免的.
3.用同一个进程中的另一个线程调用 TerminateThread()函数(必须避免);
4.终止该线程所在的进程(绝对避免);

但是要说_endthreadex完全没有用肯定是不对的,_endthreadex并不是一个过时的函数,正确的使用并不会带来问题。
比如在线程的主函数中,return是_endthreadex的一个良好替代,就像main函数里面return是exit()或ExitProccess()的良好替代一样,但是这不表示exit函数没用。比如线程调用了一个子函数,如果子函数决定退出线程,return是没用的,_endthreadex即可终结线程。

但是这个设计不好,因为可能造成LZ提出的资源泄漏。尤其考虑到后台线程终结后的资源泄漏比主线程的资源泄漏更要命(主线程退出后,进程就退出了,OS会清理一切资源,无所谓泄露不泄露,而子线程退出后主线程可能还会运行很久,并且可能有大量的同类型的子线程退出,会造成要命的泄露)
良好的设计还是返回线程的主函数,让threadproc来决定是不是要退出,从这个意义上说,_endthreadex没有必要。微软也指出,有些程序员就是要调用exit系列函数(ExitThread,ExitProccess等),没辙,只好提供了。

时间: 2024-09-25 23:34:50

C/C++中退出线程的四种解决方法_C 语言的相关文章

ubuntu中打开终端的三种解决方法_C 语言

这个不应该称得上是一个问题,但是,发现对于新手,确实是个难题因为少有人能够提到这一点,基本都是上来就直接讲用到的命令.我开始的时候也曾经被这个问题困扰着,后来,搜了一会儿才弄明白.1.在菜单内的附件上面有2.在运行命令的输入框打开3-..--------------------------------------------------------------------------------1.很好弄,在左上角的菜单上点一下,出来一列,在里面选择[附件] 中的[终端],点一下就OK.那是快捷

浅析C++中boost.variant的几种访问方法_C 语言

Boost.Variant Variant库包含一个不同于union的泛型类,用于在存储和操作来自于不同类型的对象.这个库的一个特点是支持类型安全的访问,减少了不同数据类型的类型转换代码的共同问题. Variant 库如何改进你的程序?      •对用户指定的多种类型的进行类型安全的存储和取回      •在标准库容器中存储不同类型的方法      •变量访问的编译期检查      •高效的.基于栈的变量存储 Variant 库关注的是对一组限定类型的类型安全存储及取回,即非无类的联合.Boo

求数组中最长递增子序列的解决方法_C 语言

存储扩展算法n2编程c 写一个时间复杂度尽可能低的程序,求一个一维数组(N个元素)中的最长递增子序列的长度.例如:在序列1,-1,2,-3,4,-5,6,-7中,其最长的递增子序列为1,2,4,6 或者 -1,2,4,6.(编程之美P198-202)分析与解法根据题目的要求,求一维数组中的最长递增子序列,也就是找一个标号的序列b[0],b[1],-,b[m](0 <= b[0] < b[1] < - < b[m] < N),使得array[b[0]]<array[b[1

将字符串str1复制为字符串str2的三种解决方法_C 语言

1.自己编写函数,将两个字符串进行复制 复制代码 代码如下: #include<iostream>using namespace std;int main(){   char str1[]="I love China!",str2[20];   void Strcpy(char *p1,char *p2);   Strcpy(str2,str1);   cout<<"str1: "<<str1<<endl;   cou

基于Android中实现定时器的3种解决方法_Android

在Android开发中,定时器一般有以下3种实现方法:一.采用Handler与线程的sleep(long)方法二.采用Handler的postDelayed(Runnable, long)方法三.采用Handler与timer及TimerTask结合的方法下面逐一介绍:一.采用Handle与线程的sleep(long)方法Handler主要用来处理接受到的消息.这只是最主要的方法,当然Handler里还有其他的方法供实现,有兴趣的可以去查API,这里不过多解释.1. 定义一个Handler类,用

基于Android中实现定时器的3种解决方法

在Android开发中,定时器一般有以下3种实现方法: 一.采用Handler与线程的sleep(long)方法 二.采用Handler的postDelayed(Runnable, long)方法 三.采用Handler与timer及TimerTask结合的方法 下面逐一介绍: 一.采用Handle与线程的sleep(long)方法 Handler主要用来处理接受到的消息.这只是最主要的方法,当然Handler里还有其他的方法供实现,有兴趣的可以去查API,这里不过多解释. 1. 定义一个Han

ERP中“分数问题”的两种解决方法研究

在ERP使用中,往往会遇到"分数问题",最常见的就是包装箱的问题.如:一个包装箱里,装3个成品,那么每个成品的用量就是三分之一的纸箱.在手工作业中,直接可以用分数来表示.但是,由于现在主流数据库基本上都不支持分数的表示方法,只能用小数代替. 若用系统计算物料需求量,就会出现这个问题:一个成品纸箱的用量为0.33333,那么300个成品用量为99.999个,而实际需要却是http://www.aliyun.com/zixun/aggregation/11629.html">

C语言中结构体(struct)的几种初始化方法_C 语言

本文给大家总结的struct数据有3种初始化方法      1.顺序      2.C风格的乱序      3.C++风格的乱序 下面通过示例代码详细介绍这三种初始化方法. 1)顺序 这种方法很常见,在一般的介绍C的书中都有介绍.顺序初始化的特点是: 按照成员定义的顺序,从前到后逐个初始化:允许只初始化部分成员:在被初始化的成员之前,不能有未初始化的成员. 示例: struct User oneUser = {10, "Lucy", "/home/Lucy"}; 2

C++线程池的简单实现方法_C 语言

本文以实例形式较为详细的讲述了C++线程池的简单实现方法.分享给大家供大家参考之用.具体方法如下: 一.几个基本的线程函数: 1.线程操纵函数: int pthread_create(pthread_t *tidp, const pthread_attr_t *attr, (void*)(*start_rtn)(void *), void *arg); //创建 void pthread_exit(void *retval); //终止自身 int pthread_cancel(pthread_