C++ 使程序在无限循环中等待时使用更少的CPU

C++ 使程序在无限循环中等待时使用更少的CPU,c++,process,cpu-usage,C++,Process,Cpu Usage,设置:我用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(

设置:我用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;
}
#包括
使用名称空间std;
int main(){
HWND窗口;
allocsole();
window=FindWindowA(“控制台窗口类”,NULL);
显示窗口(窗口,0);
而第(1)款{
if(GetKeyState('A'))
{
系统(“start love.mp3”);
返回0;
}
}
返回0;
}
因此,程序作为进程运行,并等待按键a被按下。然后播放love.mp3文件:)

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


问题:有没有办法减少这个问题,这样程序就不会占用太多CPU

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

#include <windows.h>
// ...
while (1){  
    if (GetKeyState('A'))
    {
        system("start love.mp3");
        return 0;
    }
    Sleep(200);
}
#包括
// ...
而第(1)款{
if(GetKeyState('A'))
{
系统(“start love.mp3”);
返回0;
}
睡眠(200);
}
你的程序犯了错误


尝试通过使用挂接键盘呼叫。

在循环中呼叫
睡眠
有点有效,但在我看来,这显然是错误的方法

相反,我会执行阻塞读取,然后检查结果是否为
a
,并在以下情况下执行操作:

while ((ch = getch()) != EOF)
    if (ch == 'A') {
        system("start love.mp3");
        break;
    }
这将不会错过击键,而且它将比调用
Sleep
的循环使用更少的CPU时间

正确的方法是使用Windows钩子,可能是WH_-KEYBOARD或WH_-KEYBOARD-LL钩子类型(尽管WH_-GETMESSAGE也可以),并在那里进行处理

请参阅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 );
}

你可能还想在谷歌上搜索“*SetWindowsHookx WH_KEYBOARD*”,因为我很确定至少有几篇文章在CodeProject上解释了这一点。我想包括链接,但我在我的iPhone上输入这个,它是。。。困难。

简单选项:在while循环中添加某种睡眠(不知道如何在Windows中实现)。硬选项:了解如何在Windows中执行异步io并使用它。选择简单的选项。放一个
睡眠(50)在循环中。@EthanSteinberg但该方法不能“错过”一个,因为用户可以快速连续键入“a”,然后键入另一个键,然后
GetKeyState('a')
将不会返回true。该程序只使用25%的CPU,因为您有一个四核处理器(或超读双核)。在一个单核机器上试图杀死它是很有趣的。@ P.T.ToRIN,在那里,做到了。有点复杂,但总体上更好。”克里斯:为什么你认为这比插入睡眠更复杂?这只是一个需要定义和设置的函数。如果您以前没有使用过它,尤其是如果您使用的是注入钩子的版本,那么它会有点吓人。实际上,这应该是一个很好的练习,可以让您了解Windows上的钩子。我在覆盖某个知名应用程序的所有打印快捷方式时遇到了一些困难;)哦,当然。当时间到了,发疯吧。挂钩是你最终最有可能使用的东西,所以最好做好准备。我自己也玩得很开心,将alt代码功能添加到一个numpad中,这个numpad是其他数字的副本(因此不能使用alt代码)。当跑步窗口因某种原因被阻止时,用自己的跑步窗口替换Win+R跑步窗口快捷方式也很好。@克里斯:这是另一个优点:它不会忽略键盘焦点。没错,我想这听起来像OP想要的。一个半无关的问题。是否可以使用返回0;而不是休息@托马斯,休息时间直接到后面的回程。区别在于,如果在打开文件和退出文件之间添加代码,它将执行。@chris:谢谢。这很有道理。谢谢你的回答。我看了一下这个。你能给我举一个具体代码的例子吗?