While loop using a lot of CPU time
Asked Answered
T

3

2

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.

Tope answered 16/9, 2009 at 4:10 Comment(3)
Make key capturing event-based, rather than poll-based.Macedo
Is there any reference or websites you suggest?Tope
I'd be gutted if a while loop didn't consume 100%Sickness
M
6

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.)

Meredeth answered 16/9, 2009 at 4:21 Comment(2)
Can you give me an example or direct me to a site that does the "listening?" Please and thanksTope
Games are usually CPU-unbounded and will pretty much use it all. Well Behaved windows-hosted games will be coded to insure that they allow SOME processing outside their scope to insure the system has enough CPU cycles for it's own maintenance. I've seen games implemented with both poll-base and event-based input semantics, but in the end it doesn't really matter as the game loop needs to snapshot it's view of user-activity once per frame just like previously stated (it's a consistency thing).Euglena
B
3

Basically, you want to use this function:

HHOOK SetWindowsHookEx(
  __in  int idHook,
  __in  HOOKPROC lpfn,
  __in  HINSTANCE hMod,
  __in  DWORD dwThreadId
);

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()

Bullock answered 19/4, 2010 at 7:55 Comment(0)
C
1

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

  1. It will be less of a CPU burden on the LowLevelKeyboardProc, which is important for low level hooks.
  2. It works for other applications that aren't monitoring every keystroke.
Chong answered 19/4, 2010 at 7:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.