[Windows] CloseHandle到底做了什么

https://docs.microsoft.com/en-us/windows/win32/api/handleapi/nf-handleapi-closehandle

https://docs.microsoft.com/en-us/windows/win32/sysinfo/kernel-objects

 

通常情况下,CloseHandle内部先将对内核对象的引用计数 -1 ,如果发现引用计数为0,则释放此内核对象。

但是有如下几种例外:

1)线程Handle,对线程句柄CloseHandle,即便让引用计数为0 ,也不会导致线程退出 。

2)进程Handle,同线程 。

3)Socket不可以使用CloseHandle,应当使用CloseSocket 。 

4)不要对注册表键值使用CloseHandle,使用 RegCloseKey 。

 

注:CloseHandle的潜台词 “我不再想操作这个内核对象了,如果本次调用会导致内核对象的应用技术为0,那么系统将会回收内核对象”

 

内核对象的句柄是进程独立的,同一个内核对象,可以有N个句柄,每个进程都可以持有同一个内核对象的一个句柄。

进程要么通过创建内核对象的方式获得 一个句柄,要么通过打开一个已经存在的内核对象获得一个句柄。

单个进程打开句柄的最大数量是 2的24 次方个。注意这里是单进程,也就是说每个进程都可以打开这么多。

但是,句柄存储在内核地址区域,因此最大句柄数量也受物理内存容量的约束。

任何进程都可以通过api创建一个句柄来引用某个已经创建的内核对象。只要知道内核对象的名称即可完成此操作。

可见,内核对象是内核级别的,句柄是进程级别的,每个进程都可以有自己的句柄指向那个内核对象,内核为我们
维护计数器,当所有进程中指向内核对象的句柄都关闭时,内核对象被系统回收。
此外,内核对象是由名字的,任何进程都可以通过这个名字来创建一个指向这个内核对象的句柄。

每种内核对象都有自己特定的一套权限控制。

很多内核对象都支持在单个进程中创建多个句柄,前提是需要知道内核对象的名字。比如CreateEvent 和 OpenEvent。
这样可以产生多个HANDLE,而且每个HANDLE都可以独立设置自己的权限控制。

如果想复制HANDLE,则可以通过DuplicateHandle来创建一个一模一样的HANDLE。

(!)当且仅当所有进程对于某个内核对象的HANDLE都被关闭,这个内核对象才会被销毁,windows中这很危险,一旦有
一个持有很多内核对象HANDLE的进程卡死了,那么这些内核对象都不会释放。

应用程序退出时会自动回收自己创建的所有HANDLE。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值