while 循环占用大量 CPU 时间
我正在出于个人兴趣创建一个击键记录器,也想知道如何捕获它们并将其用作函数(如快捷键)。
我在此处获取了了解键盘记录器和 GetAsyncKeyState() 如何工作的代码。
我让它在 Code::Blocks 下运行,但最奇怪的是,当我检查任务管理器时,我的 CPU 使用率上升到 100%。当我关闭程序时,它会降低,当我重新打开它时,它会恢复到 100%。
我认为这是因为无限 while 循环不断检查输入,但我想知道是否有任何方法可以在不丢失功能的情况下减少 CPU 使用率。
PS 我如何制作快捷键?例如,按Ctrl+E使程序退出。
I am creating a keystroke logger for my personal interest, as well wanting to know how to capture and use them as functions (like key shortcuts).
I got the code to learn how keylogger and GetAsyncKeyState() work here.
I got it to run under Code::Blocks, but the weirdest things is that when I check my task manager, my CPU Usage rises to 100%. When I close the program, it goes back down, and goes back up to 100% when I turn it back on.
I presume it's because of the infinite while loop constantly checking for inputs, but I want to know if there's any way to decrease the CPU usage without losing function.
P.S How would I make a key shortcut? For example, pressing Ctrl+E to make the program exit.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的程序本质上会耗尽所有 CPU 时间,因为它永远没有理由停止执行 - 当它到达循环末尾时,它会立即再次开始,并且没有理由延迟循环体内的任何处理。
大多数应用程序不会连续轮询键盘的状态,而是侦听操作系统广播的键盘事件。在侦听事件时,您的程序不需要消耗 CPU 时间,因此将休眠直到事件发生,从而释放处理器以供使用。
(游戏通常是一个例外,因为它们经常会轮询键盘状态。但是,它们通常会限制执行此操作的频率 - 通常最多一帧一次 - 因此 CPU 使用率仍然有限。)
Your program essentially eats up whatever CPU time it can because it never has a reason to stop executing - when it hits the end of the loop it immediately begins again, and there's no reason to delay in any of its processing within the loop body.
Most applications don't continuously poll the state of the keyboard, but instead listen for keyboard events broadcast by the OS. While listening for an event, your program has no need to consume CPU time and thus will sleep until an event occurs, freeing the processor for usage until then.
(Games are often an exception to this, in that they'll often poll the keyboard state. However, they typically limit how often they do this - usually to once a frame at most - and thus the CPU usage is still bounded.)
基本上,您想使用这个函数:
您可以阅读参数的含义(并且有很多示例),但回答您问题的部分是第二个参数。您将 lpfn 设置为指向回调函数,每次按下某个键时,您的函数(记录击键的函数)都会被调用。
它不仅仅适用于键盘事件,请查看: SetWindowsHook()
Basically, you want to use this function:
You can read up on what the parameters mean (and there's plenty of examples around) but the part that answers your question is the second parameter. You set
lpfn
to point to a callback function, and every time a key is pressed your function (the one that logs the keystroke) gets called.It's not just for the keyboard events either, check it out: SetWindowsHook()
在 Windows 上,您需要插入 低级键盘挂钩 与 Windows API。然后您将在 LowLevelKeyboardProc 函数,然后您可以使用它来记录日志。这将使用几乎 0% 的 CPU,并保证捕获每个键。
至于处理全局按键以退出记录器,您可以在 LowLevelKeyboardProc 中查找它,因为您将拦截每个按键,但更好的解决方案是使用 RegisterHotKey 然后在消息循环中查找 WM_HOTKEY 事件。这是一个更好的解决方案,因为
On Windows, you need to insert a low level keyboard hook with the windows API. Then you will get a callback on your LowLevelKeyboardProc function, which you can then use to log. This will use pretty much 0% CPU and is guaranteed to catch every key.
As for handling a global key press to quit the logger, you could look for it in LowLevelKeyboardProc since you will be intercepting every key, but a better solution is to use RegisterHotKey and then look for WM_HOTKEY events in the message loop. It is a better solution because