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等),没辙,只好提供了。
相关推荐
-
解析C/C++中如何终止线程的运行
想要终止线程的运行,可以使用以下方法: 1.线程函数返回(最好使用该方法). 2.通过调用ExitThread函数,线程将自行撤消(最好不使用该方法). 3.同一个进程或另一个进程中的线程调用TerminateThread函数(应避免使用该方法). 4.ExitProcess和TerminateProcess函数也可以用来终止线程的运行(应避免使用该方法). 下面将详细介绍终止线程运行的方法:1-4,并说明线程终止运行时会出现何种情况:5. 1.线程函数返回 始终都应该将线程设计成这样的形式,即
-
C++选择文件夹代码的封装
本文实例讲述了C++选择文件夹代码的封装,分享给大家供大家参考.具体方法如下: 该实例分为DirDialog.h头文件与DirDialog.cpp源文件. DirDialog.h头文件代码如下: 复制代码 代码如下: #pragma once #ifndef __DIRDIALOG_H_HH #define __DIRDIALOG_H_HH #include <Shlobj.h> class CDirDialog { protected: BROWSEINFO m_bi;
-
C++内核对象封装单实例启动程序的类
复制代码 代码如下: //File Name: Singleton.h#pragma once class Singleton{private: CString strGUID; CString strMapFileGUID; HANDLE m_hSingleton; public: Singleton(); ~Singleton();public: void AppStart (const HWND & hWnd) const;}; 复制代码 代码如下: //Fi
-
C++动态数组类的封装实例
C++中的动态数组(Dynamic Array)是指动态分配的.可以根据需求动态增长占用内存的数组.为了实现一个动态数组类的封装,我们需要考虑几个问题:new/delete的使用.内存分配策略.类的四大函数(构造函数.拷贝构造函数.拷贝赋值运算符.析构函数).运算符的重载.涉及到的知识点很多,对此本文只做简单的介绍. 一.内存分配策略 当用new为一个动态数组申请一块内存时,数组中的元素是连续存储的,例如 vector和string.当向一个动态数组添加元素时,如果没有空间容纳新元素,不可能简单
-
C++进程共享数据封装成类实例
本文实例讲述了C++进程共享数据封装成类的方法,分享给大家供大家参考.具体方法如下: ShareMemory.cpp源文件如下: 复制代码 代码如下: #include "ShareMemory.h" CShareMemory::CShareMemory(const char* pszMapName, int nFileSize, BOOL bServer):m_hFileMap(NULL),m_pBuffer(NULL) { if (bServer) //是服
-
C++封装线程类的实现方法
本文实例讲述了C++封装线程类的实现方法.分享给大家供大家参考.具体方法如下: 复制代码 代码如下: // 给主窗口的通知消息 #define WM_CUTTERSTART WM_USER + 100 // wParam == xxx lParam==xxxx /* 外面调用这个类时,只需要IsRunning() Startxxx(xxx) Suspendxxx() Resumexxx() Stopxxx() */ /* m_bContinue在真正的工作代码Do
-
C++实现多线程查找文件实例
主要是多线程的互斥 文件 的查找 多线程互斥的框架 复制代码 代码如下: //线程函数 UINT FinderEntry(LPVOID lpParam) { //CRapidFinder通过参数传递进来 CRapidFinder* pFinder = (CRapidFinder*)lpParam; CDirectoryNode* pNode = NULL; BOOL bActive = TRUE; //bActive为TRUE,表示当前线程激活
-
C++开发:为什么多线程读写shared_ptr要加锁的详细介绍
我在<Linux 多线程服务端编程:使用 muduo C++ 网络库>第 1.9 节"再论 shared_ptr 的线程安全"中写道: (shared_ptr)的引用计数本身是安全且无锁的,但对象的读写则不是,因为 shared_ptr 有两个数据成员,读写操作不能原子化.根据文档(http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm#ThreadSafety), shared_ptr 的线程
-
c++版线程池和任务池示例
commondef.h 复制代码 代码如下: //单位秒,监测空闲列表时间间隔,在空闲队列中超过TASK_DESTROY_INTERVAL时间的任务将被自动销毁const int CHECK_IDLE_TASK_INTERVAL = 300;//单位秒,任务自动销毁时间间隔const int TASK_DESTROY_INTERVAL = 60; //监控线程池是否为空时间间隔,微秒const int IDLE_CHECK_POLL_EMPTY = 500; //线程池线程空闲自动退出时间间隔
-
C++线程同步实例分析
本文实例分析了C++线程同步问题,分享给大家供大家参考.具体分析如下: 该实例设置全局变量g_bContinue,在主线程中设置全局变量g_bContinue,工作线程检测该全局变量,实现主线程控制工作线程的目的. 打印出的g_cnt1与g_cnt2的数值不同,是因为线程调试时时间片的切换. 具体代码如下: // countError.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <Windows.h> DWORD
-
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_
-
C/C++ 多线程的学习心得总结
个人觉得在学习多线程编程之前最好先了解进程和线程的关系, 然后在学习线程工作方式的过程中动手写个(我是从抄开始的)多线程的小程序, 会对学习多线程有很大的帮助, 否则只有理论是很抽象的. 在学习多线程编程之前, 必须先知道什么是 线程函数, 线程函数就是另一个线程的入口函数. 默认情况下一个我们所写的代码都是只有一个线程的, 而这个线程的入口函数就是main() 函数, 这是系统默认的. 而我们创建的另一个线程也需要一个函数来进入, 这个函数就叫做线程函数. 在C/C++中, 可以调用 '运行期
随机推荐
- Angular的MVC和作用域
- 计算机指令
- VBS教程:函数-LoadPicture 函数
- 正值表达式匹配html标签的属性值
- 深入探究Django中的Session与Cookie
- PHP环境搭建的详细步骤
- PHP中unset,array_splice删除数组中元素的区别
- 利用php抓取蜘蛛爬虫痕迹的示例代码
- PHP操作数组相关函数
- 基于mysql事务、视图、存储过程、触发器的应用分析
- 详解Android提交数据到服务器的两种方式四种方法
- Sqlserver 2005使用XML一次更新多条记录的方法
- range 标准化之获取
- Android编程实现基于局域网udp广播自动建立socket连接的方法
- .NET实现魔方游戏(一)之任意阶魔方的表示
- 一个简单的PHP验证码实现代码
- php获取指定数量随机字符串的方法
- [基础知识]Linux新手系列之一
- vue嵌套路由与404重定向实现方法分析
- Vue实现6位数密码效果