C++进阶—> CloseHandle详解及CloseHandle后线程未停
2017-10-26 14:14
323 查看
函数说明
BOOL CloseHandle(HANDLE hObject);参数
hObject :代表一个已打开对象handle。
返回值
TRUE:执行成功;
FALSE:执行失败,可以调用GetLastError()获知失败原因。
函数用于关闭一个内核对象。
CloseHandle到底做了什么?
当调用CloseHandle成功后,相关的内核对象的引用计数被减1。这个函数做的工作就这么多。它并没有真正的关闭内核对象,只是将计数减1,也就是说,这个时候,如果这个内核对象的引用计数不为0的话,内核对象依然存在,如果你有办法找到他,那么你依然可以操作他。
一个比较常见的问题:
CreateThread后立即CloseHandle,为什么线程还在运行?
可以这样认为,CreateThread之后,线程的内核对象的引用计数为2,CloseHandle之后,如果线程还没有结束,那么他的引用计数是1,不是0,此时,系统不会回收内核对象,所以线程还在执行。直到线程执行结束,引用计数变成了0,此时,系统回收。
内核对象什么时候被删除?
以下两种情况,内核对象会被删除--系统回收:当内核对象的引用计数为0的时候
进程结束后
如果内核对象的引用计数不为0,但是相关的进程都已经结束了,那么该内核对象会被系统回收。
参考:
进程确实没有机会执行自己的清除操作,但是操作系统可以在进程之后进行全面的清除,使得所有操作系统资源都不会保留下来。这意味着进程使用的所有内存均被释放,所有打开的文件全部关闭,所有内核对象的使用计数均被递减,同时所有的用户对象和GDI对象均被撤消。
----摘自Windows核心编程 第四版 4.3.3
内核对象泄露
内核对象在使用完毕之后,没有及时调用CloseHandle关闭,在该进程运行期间,将造成内核对象泄露。内核对象泄露会对系统造成一定程度的负面影响,但进程结束退出后,操作系统会自动回收这些内核对象。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
hThread = CreateThread( NULL, 0, ThreadFunc, NULL, 0, &dwThreadId);
CloseHandle(hThread);
如上面这样的代码,原因为:创建线程后返回了线程句柄,新创建的线程内核对象的使用计数是2,一个是线程本身,一个是创建线程的线程,创建线程的线程closehandle后,新的线程的内核对象使用计数为1,当这个新线程结束运行后内核对象的使用计数还要减1,这时内核对象的使用计数是0,则系统会自动删除新线程的内核对象,这是正常的处理流程。
如果不调用CloseHandle();则新线程运行结束后,由于使用计数为1,所以不会删除线程内核对象,这样就会造成内存泄漏。当然在整个程序运行结束后,操作系统会回收这些内存,因此可以知道如果不调用CloseHandle()的话,在程序运行阶段会造成内存泄漏!
本文参考:
《Windows核心编程 第四版》
http://blog.csdn.net/mvtechnology/article/details/72674524
相关文章推荐
- C++进阶—>子类、父类、父父类间虚函数调用详解
- C++进阶—>CreateEvent控制线程
- C++进阶—>以操作系统的角度述说线程与进程
- C++进阶—>线程优先级与线程安全
- C++进阶—>终止线程的运行
- C++进阶—>const和define机制剖析
- 关于C++ 学习的几点 理解 之 c++关键字详解(volatile,mutable,explicit,dynamic_cast<T>(expression))等
- C++进阶—>带你理解多字节编码与Unicode码
- 操作系统:线程间的同步->【转】条件变量(Condition Variable)详解
- 8.[个人]C++线程入门到进阶(8)----经典线程同步与互斥总结
- [置顶] 从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)
- 我的Android进阶之旅------>HTTP 返回状态值详解
- 9.[个人]C++线程入门到进阶(9)----线程与进程的区别
- c++的boost库多线程(Thread)编程(线程操作,互斥体mutex,条件变量)详解
- C++进阶学习——线程基类的设计(Linux)
- C++ 进阶——object slicing 与虚函数与dynamic_cast<>
- C++进阶—>Win32 多线程的创建方法和基本使用
- C++进阶—>Socket通信那点事
- 10.[个人]C++线程入门到进阶(10)----多线程经典面试题
- 从零开始学C++之boost库(一):详解 boost 库智能指针(scoped_ptr<T> 、shared_ptr<T> 、weak_ptr<T> 源码分析)