中断 (n)curses 获取传入信号

2024-04-02

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

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

有没有一种便携式的方式来中断getch?我目前的做法是ungetch信号处理程序中的虚拟密钥,但我不确定这是否允许。实际上,我找不到任何关于curses函数是否可以在信号处理程序中使用这一事实的文档。知道如何正确处理这个问题吗?

Regards


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

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为此,您必须记住为那些这样做的系统处理该伪密钥,这就是为什么我们也捕获它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

中断 (n)curses 获取传入信号 的相关文章

随机推荐

  • Visual Studio 代码:缺少 X509Certificate2UI

    尝试使用时出现以下错误X509Certificate2UI在 VS 代码中 命名空间 System Security Cryptography X509Certificates 中不存在类型或命名空间名称 X509Certificate2U
  • 递归的优点和缺点是什么?

    关于在排序算法中使用递归而不是非递归方法 或者就此而言 任何算法的优点和缺点是什么 大多数情况下 递归速度较慢 并且占用更多堆栈 递归的主要优点是 对于像树遍历这样的问题 它使算法变得更容易或更 优雅 看看一些比较 link http pa
  • Oracle 是否存储 Number 数据类型的尾随零?

    当我在表中存储数值并在 SQL Developer 中查询该表时 它没有显示数字数据类型的尾随零 create table decimal test decimal field number 10 insert into decimal t
  • 使用强化学习训练神经网络

    我了解前馈神经网络的基础知识 以及如何使用反向传播算法训练它们 但我正在寻找一种可以用于通过强化学习在线训练 ANN 的算法 例如 车杆向上摆动 http www google com search q cart 20pole 20swin
  • 带有子项的 ViewComponents

    我可以在这样的页面中使用 ViewComponents 吗
  • 将 CSV 数据导入 Google 表格

    当尝试使用IMPORTDATA该文件的函数 https www kaggle com stefanoleone992 fifa 20 complete player dataset players 20 csv https www kagg
  • JSF 获取托管 bean 中的当前操作

    当用户点击任意一个commandButton 然后在托管bean中调用相应的操作 是否可以从以下位置获取此操作名称 PostConstruct方法还是来自事件监听器方法 按钮的名称 值对本身可作为 HTTP 请求参数以通常的方式使用 想象一
  • 为什么我的 MVC3 Intranet 站点 Windows 身份验证在发布时不起作用

    我们有一个使用 MVC3 和实体框架的简单 Intranet 站点 一切正常 可以在 Visual Studio 中进行调试 当我将站点发布到本地盒子 IIS7 5 Web 服务器或同一域上的开发盒子时 系统会提示我输入用户名和密码 但它不
  • JS中如何获取对象数组的特定属性?

    我有以下代码和测试数据 const getNestedObject nestedObj pathArr gt return pathArr reduce obj key gt return obj obj key undefined obj
  • Visit_Psych_Nodes_Alias:未知别名:默认(Psych::BadAlias)

    我从 ruby 2 7 1 更新到 3 1 1 然后删除 Gemfile lock 并运行bundle update 它位于开发分支上 所以如果这是一个坏主意我可以扔掉它 我只是想看看它是否有效 bundle update成功了 但是当我启
  • knockout.js 将表单加载到 viewModel 中

    我目前正在成功使用 knockout js 来处理应用程序中的所有数据绑定 但是 在每个页面加载时 在我的 document ready 中 我正在执行初始异步数据加载 如下所示 document ready getData 但是 是否可以
  • pandas 附加到具有不同名称的列

    如何附加2个具有不同列名的不同数据框 a pd DataFrame id 0 1 2 3 countryid 22 36 21 64 famousfruit banana apple mango orange famousanimal mo
  • 有什么方法可以让用户上传的 SVG 图像免受代码注入等影响?

    我想在网站上显示用户上传的 SVG 图像 但它们很容易被利用 https security stackexchange com questions 11384 exploits or other security risks with sv
  • 使用 DOM 样式通过 Javascript 获取或更改 CSS 类属性

    我的目标是更改表中列的背景颜色 而无需按 ID 或名称单独寻址每个数据条目 我知道有几种方法可以做到这一点 确切地说我已经尝试了 3 种 但每种方法都遇到了问题 为了简单明了起见 在这个问题中 我问如何使用元素 样式 背景颜色 http w
  • 在 JavaFX HTMLeditor 中设置本地图像

    我正在寻找一种使用 JavaFX HTMLEditor 的 setHtmlText 来添加local图像 我可以添加远程图像没有问题 HTMLEditor editor new HTMLEditor editor setHtmlText i
  • 使用充气城堡正确创建带有中间证书的新证书

    所以我的问题如下 基本上我想使用 bouncy castle jdk16 版本 1 46 创建一个证书链 一般来说 我对充气城堡和 java security 相当陌生 所以如果我的方法可能完全错误 但无论如何 这就是我所做的 到目前为止
  • 当一张表小得多时,以编程方式连接表还是使用 SQL Join 语句更快?

    当一张表小得多时 以编程方式连接表还是使用 SQL Join 语句更快 更具体地说 如何从hashmap
  • 如何在 Dart 中构建单例?

    单例模式确保只创建一个类的一个实例 我如何在 Dart 中构建它 感谢达特工厂建造者 https www dartlang org guides language language tour factory constructors 构建单
  • Flutter本地数据库存储

    目前我正在创建一个用户注册标准 它有三个注册页面 对于每次完成的用户注册页面 我想将其存储在本地存储中 如果用户在第 3 级注册之前关闭应用程序 我想显示已完成页面的输入详细信息 而无需调用 api 那么 这是在 flutter 中本地存储
  • 中断 (n)curses 获取传入信号

    我的一个程序使用 ncurses 来绘制一个小 tui 我的目标之一是使其能够移植到其他诅咒实现中 这意味着我想捕获终端仿真器在调整大小操作时发出的 SIGWINCH 并更新我的 tui 以遵循更改后的几何形状 而不依赖于 ncurses