8.0
深览指数
科技虎嗅·宇众不同的露萱··AI 生成
微软为什么不用指针,而要多绕一层?
文章深入剖析了Windows NT内核中HANDLE(句柄)的设计哲学,纠正了“HANDLE只是过度封装”的常见误解。作者指出,HANDLE的本质是“带权限的能力令牌”,其核心价值在于通过间接性(Indirection)实现了内核与用户态的绝对隔离,从而保障了系统安全性和长期可演进性。文章对比了Unix的“一切皆文件”与Windows的“一切皆对象”两种设计路径,并坦诚分析了HANDLE带来的资源泄漏、IPC复杂性和现代高性能场景下的局限性。适合想系统理解操作系统底层设计权衡的开发者阅读。原文 ↗
核心观点
- ▍Windows的HANDLE并非简单的封装或指针,而是内核为隔离用户态、保障安全性和可演进性而设计的带权限的能力令牌(Capability Token)。
- 01NT内核需要管理信号量、互斥锁、线程、进程等无法被抽象为“字节流”的复杂资源,强行套用Unix的“一切皆文件”会导致ioctl()爆炸。
- 02直接暴露内核对象指针会导致用户态代码依赖结构体内存布局,内核将永远无法重构,且存在巨大的安全风险。
- 03HANDLE是进程私有句柄表中的索引,绑定了访问权限(Access Mask),内核每次通过HANDLE操作资源都会进行存在性、类型和权限三重校验。
- 04NT内核通过DISPATCHER_HEADER统一了所有内核对象的同步模型,使进程、线程、事件、定时器等均可通过WaitForSingleObject/WaitForMultipleObjects统一等待。
- 05Linux在5.1内核引入pidfd_open,通过文件描述符代表进程,并在fd上附加权限检查,本质上是“换了个名字的HANDLE”。
反方 / 局限
- — HANDLE设计导致资源泄漏诊断成本极高,因为“一切皆HANDLE”使得泄漏点难以定位。
- — HANDLE强绑定进程上下文,进程间传递句柄必须使用繁琐的DuplicateHandle API,增加了IPC编写复杂度。
- — WaitForMultipleObjects有最多等待64个句柄的硬限制,无法满足现代服务器数万并发连接的需求,微软不得不引入IOCP和IORING机制来绕过。
Dave CutlerWindows NTHANDLE对象管理器DISPATCHER_HEADERWaitForMultipleObjectsDuplicateHandleIOCPIORINGpidfd微软UnixLinux
10 分钟 · 3 卡片 · 9 资料
读原文 →