You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ncurses阻塞模式下getch()被SIGALRM信号中断返回问题咨询

问题根本原因

  • POSIX 系统中,阻塞状态的慢速系统调用(wgetch 底层依赖的终端读取read调用就属于这类)在收到未设置SA_RESTART标志的信号时,会被强制中断返回,返回值为-1,同时errno被设置为EINTR。
  • 你注册 SIGALRM 信号处理函数时未开启SA_RESTART标志,每次定时器触发信号、处理函数执行完成后,正在阻塞的wgetch就会被中断,返回ERR(ncurses 定义的错误常量,通常值为-1)。
  • 你的代码没有对wgetch的返回值做合法性校验,无论返回的是有效按键还是中断错误,都会执行total_keys++逻辑,就会出现定时器触发时计数异常递增的现象。

修复方案

  • 方案一:注册信号处理函数时添加SA_RESTART标志。配置sigaction结构体时,给sa_flags字段追加SA_RESTART,该参数会让被信号中断的系统调用在信号处理结束后自动重启,wgetch会继续保持阻塞等待按键,不会提前返回:
struct sigaction sa;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = alarm_handler;
// 原有SA_SIGINFO保留,追加SA_RESTART
sa.sa_flags = SA_SIGINFO | SA_RESTART;
sigaction(SIGALRM, &sa, NULL);
  • 方案二:在wgetch返回后增加返回值校验,仅当返回值为有效按键时才执行计数和处理逻辑:
int total_keys = 0;
while (1) {
    inputchar = wgetch(mywindow);
    // 被信号中断返回ERR时,跳过后续逻辑继续等待输入
    if (inputchar == ERR) continue;
    mvprintw(LINES - 2, 2, "%d", total_keys++);
    refresh();
    switch (inputchar) {
        ...
    }
}

内容的提问来源于stack exchange,提问作者JonPC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 10:15:03