您应该遵循的一个准则是在中断例程中尽可能少地做。如果您所做的不仅仅是设置标志,那么您应该考虑重新考虑您的解决方案。
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
这个getch10th()
函数的存在。这是因为一些实现实际上会排队一个特殊的键来处理这种确切的情况(getch()
在 raise 之后强制返回SIGWINCH
)。
如果您使用上面的代码来允许那些不这样做的系统,您必须记住为那些这样做的系统处理那个虚假密钥,因此我们也捕获它。