Windows 小记 12 -- 全局快捷键引擎降低轮询效率
通常,一些软件会通过鼠标(键盘)钩子、低级键盘钩子或注册热键(当注册热键比较多时,系统每次都需要查表)的方式来实现全局快捷键,或用于捕获键盘和鼠标输入等事件。然而,在使用过程中,启动此类全局快捷键引擎时,往往会导致系统在一段时间内严重降低对 USB 设备事件的轮询效率,进而造成明显的延迟现象。
造成延迟的原因
(1)全局钩子和热键机制的工作原理:
- 全局键盘钩子 和 低级键盘钩子(通过 SetWindowsHookEx 注册)允许应用程序在所有应用程序中捕获键盘输入事件。当系统有键盘输入时,所有输入事件都会传递给这些钩子函数处理。
- 注册全局热键 使得操作系统必须监听特定的键盘组合(例如 Ctrl+Alt+T 等),并在这些组合按下时执行相应操作。正如 Microsoft 的文档中所述,每次按下某个键时,Windows 都会搜索已注册的热键。该操作可能只需要几毫秒,但这是完全可以避免的。
- 鼠标钩子 类似地,允许捕获鼠标事件,但这也会在鼠标每次移动、点击时触发事件处理。
(2)事件队列和系统性能: 钩子机制会拦截操作系统的输入消息,系统的每个输入事件(键盘或鼠标)都需要经过这些钩子来进行处理。如果钩子代码处理不够高效或者需要做耗时操作,会导致系统消息队列堵塞或延迟。这对需要高频率轮询和低延迟的 USB 设备事件(如鼠标、键盘输入等)来说,可能造成明显的性能瓶颈。
延迟表现: 当全局钩子或热键引擎占用了大量 CPU 时间,系统处理来自 USB 设备的事件(如鼠标和键盘输入)时会发生延迟,表现为 输入反应迟缓 或 系统响应变慢。这种情况在高频繁的输入事件下尤为明显,比如游戏、实时控制或需要高精度输入的应用程序中。
此外,钩子实现的引擎可能引起一些反作弊软件或 EDR 软件的风控,带来兼容性问题。
在高性能场景下解决此类问题的最佳方案是采用原始输入 RawInput。