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
相关产品推荐
相关产品推荐

