Ncurses 无缘无故神秘地使用了我所有的 CPU
Ncurses is mysteriously using all my CPU for no reason
我正在尝试使用 ncurses 编写类似 nethack 的程序。该程序运行良好,给我画了一个盒子和所有东西,而且没有吃掉我的大部分 CPU。在我添加 while(true)
循环后,它不会绘制我的盒子,当我移动我的“角色”时它会吃掉我的 CPU 的 100%。
#include <iostream>
#include <curses.h>
int main(){
std::pair<int,int> csr_pos{1,1};
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
nodelay(stdscr, TRUE);
curs_set(0);
WINDOW *win = newwin(50,80,0,0);
if(has_colors()){
start_color();
init_pair(1,COLOR_CYAN,COLOR_BLACK);
init_pair(2,COLOR_RED,COLOR_BLACK);
init_pair(3,COLOR_WHITE,COLOR_RED);
init_pair(4,COLOR_YELLOW,COLOR_BLACK);
}
/*
wattron(win,COLOR_PAIR(1));
mvwaddch(win,25,41,'@');
wattroff(win,COLOR_PAIR(1));
*/
for(int i = 0; i<80; i++){
mvwaddch(win,0,i,'#');
mvwaddch(win,49,i,'#');
wrefresh(win);
}
for(int i = 1; i<49; i++){
mvwaddch(win,i,0,'#');
mvwaddch(win,i,79,'#');
wrefresh(win);
}
while(true){
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
int ch = getch();
if(ch==KEY_LEFT){
mvwaddch(win,csr_pos.first,csr_pos.second,' ');
csr_pos.second--;
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
}
if(ch==KEY_RIGHT){
mvwaddch(win,csr_pos.first,csr_pos.second,' ');
csr_pos.second++;
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
}
wrefresh(win);
}
}
nodelay(stdscr, TRUE);
让我们看看 curses 手册页是怎么说的:
nodelay
The nodelay option causes getch to be a non-blocking call. If no input
is ready, getch returns ERR. If disabled (bf is FALSE), getch waits
until a key is pressed.
如果不清楚:在 nodelay 模式下 getch
不等待按键。马上returns。
让我们看看显示的代码接下来做了什么:
while(true){
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
int ch = getch();
// ...
所以,这现在变成了 100% CPU 绑定无限循环。 getch
总是 returns 立即。如果下面的代码检查的两个键都没有被按下,这个 while
循环会立即再次运行,并且你回到你开始的地方,一遍又一遍。
这就是显示的代码“吃掉 100%”CPU 的原因。
nodelay
模式旨在与 poll()
s 或 select()
s 的附加逻辑一起使用,直到有按键,而 getch
仅在有按键时被调用要读取的实际密钥。
我正在尝试使用 ncurses 编写类似 nethack 的程序。该程序运行良好,给我画了一个盒子和所有东西,而且没有吃掉我的大部分 CPU。在我添加 while(true)
循环后,它不会绘制我的盒子,当我移动我的“角色”时它会吃掉我的 CPU 的 100%。
#include <iostream>
#include <curses.h>
int main(){
std::pair<int,int> csr_pos{1,1};
initscr();
cbreak();
noecho();
keypad(stdscr, TRUE);
nodelay(stdscr, TRUE);
curs_set(0);
WINDOW *win = newwin(50,80,0,0);
if(has_colors()){
start_color();
init_pair(1,COLOR_CYAN,COLOR_BLACK);
init_pair(2,COLOR_RED,COLOR_BLACK);
init_pair(3,COLOR_WHITE,COLOR_RED);
init_pair(4,COLOR_YELLOW,COLOR_BLACK);
}
/*
wattron(win,COLOR_PAIR(1));
mvwaddch(win,25,41,'@');
wattroff(win,COLOR_PAIR(1));
*/
for(int i = 0; i<80; i++){
mvwaddch(win,0,i,'#');
mvwaddch(win,49,i,'#');
wrefresh(win);
}
for(int i = 1; i<49; i++){
mvwaddch(win,i,0,'#');
mvwaddch(win,i,79,'#');
wrefresh(win);
}
while(true){
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
int ch = getch();
if(ch==KEY_LEFT){
mvwaddch(win,csr_pos.first,csr_pos.second,' ');
csr_pos.second--;
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
}
if(ch==KEY_RIGHT){
mvwaddch(win,csr_pos.first,csr_pos.second,' ');
csr_pos.second++;
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
}
wrefresh(win);
}
}
nodelay(stdscr, TRUE);
让我们看看 curses 手册页是怎么说的:
nodelay
The nodelay option causes getch to be a non-blocking call. If no input
is ready, getch returns ERR. If disabled (bf is FALSE), getch waits
until a key is pressed.
如果不清楚:在 nodelay 模式下 getch
不等待按键。马上returns。
让我们看看显示的代码接下来做了什么:
while(true){
mvwaddch(win,csr_pos.first,csr_pos.second,'@');
int ch = getch();
// ...
所以,这现在变成了 100% CPU 绑定无限循环。 getch
总是 returns 立即。如果下面的代码检查的两个键都没有被按下,这个 while
循环会立即再次运行,并且你回到你开始的地方,一遍又一遍。
这就是显示的代码“吃掉 100%”CPU 的原因。
nodelay
模式旨在与 poll()
s 或 select()
s 的附加逻辑一起使用,直到有按键,而 getch
仅在有按键时被调用要读取的实际密钥。