什么是事件句柄?

Posted

技术标签:

【中文标题】什么是事件句柄?【英文标题】:What is an Event Handle? 【发布时间】:2010-12-17 13:15:59 【问题描述】:

我在一个大的旧程序中出现了句柄泄漏。使用 sysinternals handle.exe 我推断出泄漏的句柄类型是“事件”句柄。但我不确定我应该查看代码的哪些部分。是否有返回事件句柄的函数列表?

编辑:整个程序中没有一个 CreateEvent、CreateEventEx 或 OpenEvent 实例。

【问题讨论】:

【参考方案1】:

你看到多少这些泄露的句柄?

事件是由临界区隐式创建的(请参阅InitializeCriticalSection et.al.),可能还有其他一些我目前不记得的 Win32 元素。此外,它们可以由您正在使用的框架(如果有)(如 MFC)或您正在使用的库创建。

要跟踪泄漏,您可以使用仅打印断点。进入 CreateEvent 函数(使用汇编视图)并在其第一条指令上放置一个断点。然后右键单击断点,选择“当命中...”并编辑选项,这样它就不会中断调试器但会打印一些有用的信息(例如,参见 $CALLER 宏)。然后运行你的应用程序......并准备好看到一个巨大的日志。如果确实存在泄漏,您将在日志中看到重复的模式,用于识别违规者。

【讨论】:

在最初的匆忙之后,程序稳定下来,每秒创建一个或两个。 - 这个答案听起来很可行,但我要到明天才能尝试。干杯。【参考方案2】:

即使您自己不直接创建事件,操作系统或其他库代码也肯定可以并且将会。您可能想查看您的应用程序正在打开/创建的其他资源是否未被清理的可能性。有可能你真的泄漏了其他东西,但那东西带来了一个事件对象。

在 CreateEvent(和朋友)上设置一个调试器断点可能会有所帮助,以查看是什么创建了它,但如果这种情况经常发生以至于您的问题被淹没在噪音中,我不会感到惊讶。

【讨论】:

【参考方案3】:

如果您不知道哪些 DLL 或第三方组件正在调用 CreateEvent 或 CreateEventEx,请使用 Dependency Walker 查看每个 DLL 导入的内容:

http://www.dependencywalker.com/(免费)

这至少有助于将问题缩小到一组特定的交互 - 然后您需要查看对该库的所有调用并检查所有内容是否已正确清理。

【讨论】:

【参考方案4】:

据我所知,几乎唯一可以创建事件的是 CreateEvent 和 CreateEventEx。相当多的其他函数可以返回事件句柄(例如 WaitForMultipleObjects),但它是您之前创建并传递给它的句柄..

编辑:由于您的代码显然不是直接创建事件,您可能希望首先使用绕道来查看对 CreateEvent(Ex) 的调用,然后回溯堆栈以查看代码的哪一部分导致它们被创建,以及创建它们的名称。

【讨论】:

【参考方案5】:

正如其他人所提到的,CreateEvent / CreateEventEx 用于创建“事件”句柄。这些代表经常用于门控访问的同步对象,向其他线程(可能)提供信号,也可以用作锁的基础。

如果您尝试调试涉及事件句柄的泄漏,您应该尝试查找在没有相应 CloseHandle() 的情况下调用 CreateEvent(Ex) 的位置。根据您用于获取事件的框架,您可能还会发现,如果它们是另一个对象/结构的成员(例如,具有在清理时跳过的通用 HANDLE 成员变量的东西,或者指向 HANDLE 的指针等)。

如果您不记得曾在自己的代码中创建过这些对象,则可能是您在内部使用它们的另一个类或提供程序上缺少类似的 Close() 或其他清理方法。进行后台处理、发信号或提供等待操作完成的方法的事情通常是这里的嫌疑人。

创建事件句柄CreateEvent Function @ MSDNCreateEventEx Function @ MSDN

清理句柄CloseHandle Function @ MSDN

【讨论】:

【参考方案6】:

以下链接应该可以帮助您入门: http://msdn.microsoft.com/en-us/library/ms682655(VS.85).aspx

CreateEvent 和 CreateEventEx 将创建事件并将句柄返回给它们。

【讨论】:

以上是关于什么是事件句柄?的主要内容,如果未能解决你的问题,请参考以下文章

libevent

Ajf事件中的JSF句柄异常

绑定事件 addEventListener

javascript事件监听

事件监听器

复习 - JavaScript - 阶段02