【问题标题】:ncurses getch() behaviour with signalsncurses 带有信号的 getch() 行为
【发布时间】:2021-09-03 20:56:40
【问题描述】:

我的代码设置了一个计时器,它每 x 秒发送一次 SIG_ALRM。然后它进入一个调用 getch() 的输入处理循环。

    int total_keys = 0;
    while (1) {
        inputchar = wgetch(mywindow);
        mvprintw(LINES - 2, 2, "%d", total_keys++);
        refresh();
        switch (inputchar) {
            ...
        }
    }

由于我将 getch() 设置为阻塞 (wtimeout(mywindow, -1);),因此我希望 total_keys 仅在我按下某个键时才会上升,但我发现每次收到 SIG_ALRM 时,getch() 都会返回并且 total_keys 会递增。有谁知道为什么会这样?

编辑:这是我的 SIG_ALRM 处理程序

void alarm_handler(int signum, siginfo_t *si, void *ucontext) {
    timer_t *timeridp = si->si_value.sival_ptr;
    if (*timeridp == *update_timerp) {
        update();
    }
}

【问题讨论】:

  • 您有SIG_ALRM 的处理程序吗?文档说“在 ncurses 实现下,处理的信号永远不会中断 getch。”
  • 这是我的 SIG_ALRM 处理程序你的 update() 函数异步信号安全吗?
  • 我对 C 很陌生,不知道这个概念。我正在阅读它,我不确定,但可能不是。基本上我的update() 函数调用malloc 和一些诅咒函数,如wmovewinchprintw。它还设置了一些主循环使用的数据。如果printf 和其他缓冲 IO 函数不安全,我想 ncurses 对应的函数也不安全。

标签: c ncurses


【解决方案1】:

检查是否有错误返回,发生这种情况时不要处理输入。

while (1) {
    inputchar = wgetch(mywindow);
    if (inputchar == ERR) {
        if (errno == EINTR) {
            continue;
        } else {
            // report failure somehow
        }
    }
    mvprintw(LINES - 2, 2, "%d", ++total_keys);
    refresh();
    switch (inputchar) {
        ...
    }
}

【讨论】:

  • 谢谢!是的,它完美无缺,但我想知道为什么 getch() 首先会被打断。从 cmets 我认为这是因为我不应该从处理程序调用 ncurses 函数,所以也许我最好设置 timeout(0) 以使 getch 非阻塞,并从处理程序设置一个标志并在主循环。
  • 从信号处理程序调用大多数函数是不安全的。
猜你喜欢
  • 2010-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
  • 1970-01-01
相关资源
最近更新 更多