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

Linux父子进程信号处理C语言问题:子进程收信号无输出 需忽略SIGQUIT

问题排查及修复方案

代码存在的问题

  • 标准输出缓冲未刷新:printf默认采用行缓冲机制,子进程死循环中没有其他IO操作,打印内容会滞留在缓冲区不会输出到终端,导致看不到子进程的打印。
  • sigquit信号重置逻辑错误:sigquit处理函数中错误地重置了SIGINT的信号处理函数,而非SIGQUIT的,第一次收到SIGQUIT后,后续触发SIGQUIT会直接走默认行为终止子进程。
  • 信号处理函数原型不规范:POSIX标准要求信号处理函数必须携带int类型的入参,用于接收触发的信号编号,无入参的写法在部分系统上会导致调用异常。
  • 笔误问题:sighup处理函数中打印的sighub为拼写错误,应为sighup。
  • main函数返回值不规范:C标准要求main函数返回值为int类型,void写法属于非标准写法,部分编译器会抛出警告。

修复后的完整代码

// C program to implement signal handling for SIGHUP, SIGINT, SIGQUIT, SIGSEGV
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

// 标准信号处理函数原型,入参为信号编号
void sighup(int signo);
void sigint(int signo);
void sigquit(int signo);
void sigsegv(int signo);

int main()
{
  int pid;

  /* 创建子进程 */
  if ((pid = fork()) < 0) {
    perror("fork");
    exit(1);
  }

  if (pid == 0) { /* 子进程逻辑 */
    signal(SIGHUP, sighup);
    signal(SIGINT, sigint);
    signal(SIGQUIT, sigquit);
    signal(SIGSEGV, sigsegv);
    for (;;)
      ; /* 循环等待信号 */
  }

  else /* 父进程逻辑 */
  { 
    printf("\nPARENT: sending SIGHUP\n\n");
    kill(pid, SIGHUP);

    sleep(3); 
    printf("\nPARENT: sending SIGINT\n\n");
    kill(pid, SIGINT);

    sleep(3); 
    printf("\nPARENT: sending SIGQUIT\n\n");
    kill(pid, SIGQUIT);
    sleep(3);

    // 测试完成后杀死子进程退出
    kill(pid, SIGKILL);
    return 0;
  }
}

// SIGHUP处理函数
void sighup(int signo)
{
  signal(SIGHUP, sighup); /* 重置信号处理函数 */
  printf("CHILD: %d [sighup]\n", signo);
  fflush(stdout); // 强制刷新缓冲区
}

// SIGINT处理函数
void sigint(int signo)
{
  signal(SIGINT, sigint); 
  printf("CHILD: %d [sigint]\n", signo);
  fflush(stdout);
}

// SIGSEGV处理函数
void sigsegv(int signo)
{
  signal(SIGSEGV, sigsegv); 
  printf("CHILD: %d [sigsegv]\n", signo);
  fflush(stdout);
}

// SIGQUIT处理函数
void sigquit(int signo)
{
  signal(SIGQUIT, sigquit); // 修正:重置SIGQUIT的处理函数
  printf("CHILD: %d [sigquit]\n", signo);
  fflush(stdout);
}

效果说明

修复后子进程收到信号会先打印对应信号编号,之后继续运行,不会触发信号的默认行为(比如SIGQUIT的默认core dump、终止进程行为),完全符合你“忽略信号同时打印信号编号”的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 15:15:05