gpt4 book ai didi

c - 中断(n)诅咒传入信号

转载 作者:太空狗 更新时间:2023-10-29 16:39:04 26 4
gpt4 key购买 nike

我的一个程序使用 ncurses 来绘制一个小 tui。我的目标之一是让它更容易移植到其他 curses 实现中。这意味着我想自己捕获终端仿真器在调整大小操作时发出的 SIGWINCH,并更新我的 tui 以遵循更改后的几何形状(而不依赖于 ncurses 的调整大小工具)。由于 POSIX(据我所知)只允许访问信号处理程序中的 sig_atomic_t 变量,因此我将其中一个设置为不同的状态。在主循环中,我的程序检查状态是否已更改并在必要时更新 tui。

但是现在,当信号到达时,我的程序在 getch 中挂起。 ncurses 文档指出处理的信号永远不会中断它。这意味着 tui 的大小在按下输入键之前不会更新。

是否有任何可移植的方式来中断getch?我当前的方法是在信号处理程序中取消获取 一个虚拟键,但我不确定这是否被允许。实际上我找不到任何关于 curses 函数是否可以在信号处理程序中使用的文档。知道如何正确处理这个问题吗?

问候

最佳答案

您应该遵循的一条准则是在中断例程中尽可能少地执行操作。如果您所做的不仅仅是设置标志,那么您应该考虑重新考虑您的解决方案。

curses 系统有办法处理这个问题,但它需要开发人员做一些工作。

您将半延迟模式设置为适当的延迟,这样如果在此期间没有可用的击键,getch() 将返回 ERR。这有效地让您脱离了 getch() 调用,这样您就可以执行您需要的任何其他 curses 操作。

所以,这就是我的建议。首先,更改您的 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 运行)之间。

明智地使用它可以使您的窗口响应速度相当快,而不必担心可移植性。


有关将其付诸实践的示例,请参见以下 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;
}

精明的读者会注意到 getch10th() 函数中也存在 KEY_RESIZE。这是因为一些实现实际上会排队一个特殊的键来处理这种情况(强制 getch() 在引发 SIGWINCH 后返回)。

如果您使用上面的代码来允许那些这样做的系统,您必须记住为那些这样做的系统处理那个虚假 key ,这就是我们捕获它的原因

关于c - 中断(n)诅咒传入信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26807623/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com