转自
[url]http://blog.csdn.net/a102111/article/details/8501620[/url]
最近回顾了下多线程的东西,碰到CloseHandle函数,之前也碰到过,但是自己积累不足,所以也没理解明白。这次再次碰到,想想积累的也差不多了,索性就搞个明白。
[b]函数说明[/b]
[color=red]参数
hObject :代表一个已打开对象handle。
返回值
TRUE:执行成功;
FALSE:执行失败,可以调用GetLastError()获知失败原因。[/color]
函数用于关闭一个内核对象。
[i][b]CloseHandle到底做了什么?[/b][/i]
当调用CloseHandle成功后,相关的内核对象的引用计数被减1。
这个函数做的工作就这么多。它并没有真正的关闭内核对象,只是将计数减1,也就是说,这个时候,如果这个内核对象的引用计数不为0的话,内核对象依然存在,如果你有办法找到他,那么你依然可以操作他。
一个比较常见的问题:
CreateThread后立即CloseHandle,为什么线程还在运行?
可以这样认为,CreateThread之后,线程的内核对象的引用计数为2,CloseHandle之后,如果线程还没有结束,那么他的引用计数是1,不是0,此时,系统不会回收内核对象,所以线程还在执行。直到线程执行结束,引用计数变成了0,此时,系统回收。
[color=orange][b]内核对象什么时候被删除?[/b][/color]
以下两种情况,内核对象会被删除--系统回收:
当内核对象的引用计数为0的时候
进程结束后
如果内核对象的引用计数不为0,但是相关的进程都已经结束了,那么该内核对象会被系统回收。
[quote]参考:
进程确实没有机会执行自己的清除操作,但是操作系统可以在进程之后进行全面的清除,使得所有操作系统资源都不会保留下来。这意味着进程使用的所有内存均被释放,所有打开的文件全部关闭,所有内核对象的使用计数均被递减,同时所有的用户对象和GDI对象均被撤消。
----摘自Windows核心编程 第四版 4.3.3[/quote]
[color=red][b]内核对象泄露[/b][/color]
[color=red]内核对象在使用完毕之后,没有及时调用CloseHandle关闭,在该进程运行期间,将造成内核对象泄露。
内核对象泄露会对系统造成一定程度的负面影响,但进程结束退出后,操作系统会自动回收这些内核对象。[/color]
[url]http://blog.csdn.net/a102111/article/details/8501620[/url]
最近回顾了下多线程的东西,碰到CloseHandle函数,之前也碰到过,但是自己积累不足,所以也没理解明白。这次再次碰到,想想积累的也差不多了,索性就搞个明白。
[b]函数说明[/b]
BOOL CloseHandle(HANDLE hObject);
[color=red]参数
hObject :代表一个已打开对象handle。
返回值
TRUE:执行成功;
FALSE:执行失败,可以调用GetLastError()获知失败原因。[/color]
函数用于关闭一个内核对象。
[i][b]CloseHandle到底做了什么?[/b][/i]
当调用CloseHandle成功后,相关的内核对象的引用计数被减1。
这个函数做的工作就这么多。它并没有真正的关闭内核对象,只是将计数减1,也就是说,这个时候,如果这个内核对象的引用计数不为0的话,内核对象依然存在,如果你有办法找到他,那么你依然可以操作他。
一个比较常见的问题:
CreateThread后立即CloseHandle,为什么线程还在运行?
可以这样认为,CreateThread之后,线程的内核对象的引用计数为2,CloseHandle之后,如果线程还没有结束,那么他的引用计数是1,不是0,此时,系统不会回收内核对象,所以线程还在执行。直到线程执行结束,引用计数变成了0,此时,系统回收。
[color=orange][b]内核对象什么时候被删除?[/b][/color]
以下两种情况,内核对象会被删除--系统回收:
当内核对象的引用计数为0的时候
进程结束后
如果内核对象的引用计数不为0,但是相关的进程都已经结束了,那么该内核对象会被系统回收。
[quote]参考:
进程确实没有机会执行自己的清除操作,但是操作系统可以在进程之后进行全面的清除,使得所有操作系统资源都不会保留下来。这意味着进程使用的所有内存均被释放,所有打开的文件全部关闭,所有内核对象的使用计数均被递减,同时所有的用户对象和GDI对象均被撤消。
----摘自Windows核心编程 第四版 4.3.3[/quote]
[color=red][b]内核对象泄露[/b][/color]
[color=red]内核对象在使用完毕之后,没有及时调用CloseHandle关闭,在该进程运行期间,将造成内核对象泄露。
内核对象泄露会对系统造成一定程度的负面影响,但进程结束退出后,操作系统会自动回收这些内核对象。[/color]