2

我在一些继承的 C# winforms 代码中遇到了泄漏的句柄问题(“没有足够的配额来处理这个命令。”),所以我去使用 Sysinternals 的句柄工具来追踪它。原来是事件句柄泄漏了,所以我试着用谷歌搜索它(花了几次尝试找到一个没有返回“你的意思是:事件处理程序吗?”的查询)。据张俊峰介绍,事件句柄是使用 Monitor 生成的,就事件句柄处置和同步原语而言,可能存在一些奇怪的规则。

我不完全确定我的泄漏句柄的来源完全是由于简单的长寿对象调用了很多同步的东西,因为这段代码还处理 HID 接口和大量的 win32 编组和互操作,并且没有做任何事情我知道的同步。无论哪种方式,我都将在 windbg 中运行它并开始追踪句柄的来源,并花费大量时间学习这部分代码,但我很难找到有关什么事件的信息把手放在第一位。

事件内核对象的msdn 页面只是链接到通用同步概述......那么什么是事件句柄,它们与互斥锁/信号量/其他有什么不同?

4

2 回答 2

3

NT 内核使用事件对象来允许将信号传输到等待信号的实体。互斥量和信号量也是可等待的内核对象(Kernel Dispatcher Objects),但语义不同。我唯一一次遇到它们是在等待 IO 在驱动程序中完成时。

所以我对你的问题的理论可能是驱动程序有问题,还是你依赖专门的硬件?

编辑:更多信息(来自Windows Internals 5th Edition - Chapter 3 System Mechanics)

一些内核调度程序对象(例如互斥量、信号量)具有概念所有权。因此,当发出释放信号时,将释放一个等待线程将获取这些资源。其他人将不得不继续等待。事件不属于所有,因此可以由任何线程重置。

还有三种类型的事件:

  • 通知:发出信号,所有等待的线程都被释放
  • 同步:发出信号,释放一个等待线程,但重置事件
  • Keyed :在释放信号器的同一进程中发出一个等待线程的信号。

我学到的另一件有趣的事是关键部分c# 中的锁原语)实际上不是内核对象,而是根据需要从键控事件、互斥锁或信号量实现。

于 2010-03-03T22:46:25.743 回答
2

如果您在谈论内核事件对象,那么事件句柄将是系统保留在该对象上的句柄(Int),以便其他对象可以引用它。IE 在上面保留一个“句柄”。

希望这可以帮助!

于 2010-03-03T22:43:11.583 回答