您应该遵循的一条准则是在中断例程中尽可能少地执行操作。如果您所做的不仅仅是设置标志,那么您应该考虑重新考虑您的解决方案。
The curses
系统有办法处理这个问题,但需要开发人员做一些工作。
您将半延迟模式设置为合适的延迟,这样getch()
将返回ERR
如果在那段时间没有可用的按键。这有效地让你摆脱了getch()
调用,这样您就可以执行您需要的任何其他诅咒操作。
所以,这就是我的建议。首先,更改您的 SIGWINCH 处理程序,以便它仅设置一个标志resized
您的“主”程序可以检测到。
其次,为您的申请提供特殊形式的getch()
沿着(显然是伪代码)的思路:
def getch_10th():
set half delay mode for (for example) 1/10th second
do:
if resized:
do whatever it takes to resize window
set ch to result of real getch() (with timeout, of course)
while timed out
return ch
就效率而言,半延迟模式是永远等待(并且不处理调整大小事件)和立即返回(吸收 CPU 垃圾)之间的折衷方案。
明智地使用它可以使您的 Windows 响应相当快,而不必担心可移植性。
请参阅以下 C 程序,了解将其付诸实践的示例。一、信号与拦截函数:
#include <curses.h>
#include <signal.h>
// Flag and signal handler.
static volatile int resized = 1;
static void handle_resize (int sig) {
resized = 1;
}
// Get a character, handling resize events.
int getch10th (void) {
int ch;
do {
if (resized) {
resized = 0;
endwin();
refresh();
mvprintw (1, 0, "Size = %dx%d. \n", COLS, LINES);
refresh();
}
halfdelay (1);
ch = getch();
} while (ch == ERR || ch == KEY_RESIZE);
return ch;
}
然后一个简单的main
测试一下:
// Simplified main capturing keystrokes.
int main (void) {
WINDOW * w = initscr();
noecho();
signal (SIGWINCH, handle_resize);
for (;;) {
int ch = getch10th();
mvprintw(0, 0, "Got character 0x%02x. \n\n", ch);
}
endwin();
return 0;
}
精明的读者会注意到KEY_RESIZE
in the getch10th()
功能也一样。这是因为某些实现实际上会排队一个特殊的键来处理这种确切的情况(强制getch()
筹集后返回SIGWINCH
).
如果您使用上面的代码来允许那些系统don't为此,您必须记住为那些这样做的系统处理该伪密钥,这就是为什么我们也捕获它。