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

为何C程序接收SIGALRM信号后直接退出?如何修复?

问题分析与修复

程序退出的原因

当SIGALRM信号触发时,正在阻塞等待输入的getchar()系统调用会被信号中断,返回-1。而EOF在标准IO中的定义就是-1,因此循环里的if(ch == 'q' || ch == EOF)条件被触发,直接跳出循环导致程序退出。

修复方案

方案一:让系统调用自动重启

修改sigaction的sa_flags,添加SA_RESTART标志。这个标志会让被信号中断的阻塞系统调用自动重新执行,而不是返回错误。修改后的代码片段:

struct sigaction sa;
sa.sa_handler = thread_signal_handler;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART; // 新增该标志
sigaction(SIGALRM, &sa, NULL);

方案二:手动处理中断错误

在循环中检查getchar()返回EOF是否是因为信号中断导致的。需要引入<errno.h>头文件,当系统调用被信号中断时,errno会被设置为EINTR,此时我们可以忽略这个错误,继续等待输入。修改后的循环代码:

#include <errno.h> // 新增头文件

// ... 其余代码不变 ...

while (1)
{
    errno = 0;
    int ch = getchar();
    if (ch == 'q' || ch == EOF) {
        // 仅当不是信号中断导致的EOF时才退出
        if (errno != EINTR) {
            break;
        }
    }
}

额外提示

  • 信号处理函数中使用printf存在风险:printf不属于POSIX定义的信号安全函数,在信号处理中调用可能引发竞态或未定义行为。建议改用write系统调用替代,示例:
    write(STDOUT_FILENO, "time run out!!!\n", 16);
    
  • 如果需要定时器重复触发,将timer.it_interval设置为非0值即可,比如timer.it_interval.tv_sec = 5;,这样定时器会每隔5秒触发一次。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 23:48:24