3

设置:我在 C++ 中有这个程序:

#include <windows.h>
using namespace std;
int main(){
    HWND window;
    AllocConsole();
    window = FindWindowA("ConsoleWindowClass", NULL);
    ShowWindow(window,0);
while (1){  
if (GetKeyState('A'))
        {
    system("start love.mp3");
    return 0;
        }
    }
return 0;
}

所以程序作为一个进程运行并等待直到按键 A 被按下。然后它播放 love.mp3 文件:)

但是,当程序等待时,它会占用 25% 的 CPU 使用率。

:有没有办法减少这种情况,使程序不会消耗太多的 CPU?

4

4 回答 4

8

你的程序犯了忙等待

尝试使用SetWindowsHookEx.

于 2012-06-12T03:27:03.743 回答
7

在循环中调用Sleep是有效的,但 IMO,这显然是错误的方式。

相反,我会进行阻塞读取,然后检查结果是否为A,并在结果为 时执行您的操作:

while ((ch = getch()) != EOF)
    if (ch == 'A') {
        system("start love.mp3");
        break;
    }

这不会错过击键,而且它使用的 CPU 时间甚至比调用Sleep.

于 2012-06-12T03:27:37.717 回答
4

您可以很容易地将对 WindowsSleep()函数的调用添加到循环中。该参数以毫秒为单位,因此这将大约每秒检查键盘五次:

#include <windows.h>
// ...
while (1){  
    if (GetKeyState('A'))
    {
        system("start love.mp3");
        return 0;
    }
    Sleep(200);
}
于 2012-06-12T03:22:59.870 回答
2

正确的方法是使用 Windows 钩子,可能是 WH_KEYBOARD 或 WH_KEYBOARD_LL 钩子类型(尽管 WH_GETMESSAGE 也可以)并在那里进行处理。

在http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx查看 SetWindowsHookEx 的文档

我还没有测试过这个——只是在运行中把它搅起来——但这里有一个简单的例子,当按下“A”键时应该做你想做的事情。

LRESULT __stdcall CALLBACK LoveProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    static int love = 0;

    if((nCode == HC_ACTION) && 
       (wParam == 'A') &&      /* the key pressed was 'A' */
       (lParam & 0x40000000))  /* trigger when the key is pressed */
    {        
        if(love == 0)
            play_romantic_love_song();

        /* but don't overdo it because "Too Much Love Will Kill You" */
        love = 1;
    }

    return CallNextHookEx(hOldKeyHook, nCode, wParam, lParam );
}

您可能还想在 Google 上搜索“*SetWindowsHookEx WH_KEYBOARD*”,因为我很确定 CodeProject 上至少有几篇文章对此进行了解释。我会包含这些链接,但我是从我的 iPhone 上输入的,而且它......很难。

于 2012-06-12T04:19:37.940 回答