为何子进程既忽略exit(0)又无视sleep函数?技术求助
问题分析与解决
核心问题1:write函数长度参数错误
在this信号处理函数中:
write(STDOUT_FILENO,"Yep\n",13);
字符串"Yep\n"实际仅4字节(含换行符),但你传入了13作为长度参数,触发越界写入的未定义行为。第二个子进程收到SIGUSR1执行该函数时,大概率直接崩溃,根本无法执行后续的kill(pid, SIGUSR2),导致第一个子进程永远卡在pause(),收不到终止信号。
核心问题2:signal函数的兼容性隐患
signal函数的行为在不同系统中存在差异(比如System V风格会在处理信号后恢复默认处理方式),推荐使用标准的sigaction注册信号处理函数,确保行为一致。
修复后的代码
#include <sys/types.h> #include <unistd.h> #include <stdio.h> #include <stdlib.h> #include <sys/wait.h> #include <signal.h> #include <string.h> void this(int sig) { const char msg[] = "Yep\n"; write(STDOUT_FILENO, msg, strlen(msg)); // 使用准确的字符串长度 } void fuckingdie(int sig) { exit(0); } int main() { // 用sigaction替代signal,保证信号处理行为稳定 struct sigaction sa1, sa2; memset(&sa1, 0, sizeof(sa1)); sa1.sa_handler = this; sigaction(SIGUSR1, &sa1, NULL); memset(&sa2, 0, sizeof(sa2)); sa2.sa_handler = fuckingdie; sigaction(SIGUSR2, &sa2, NULL); pid_t pid = fork(); pid_t pid2; if (pid < 0) { exit(-1); } else if (pid == 0) { pause(); sleep(100); printf("error\n"); } else { pid2 = fork(); if (pid2 < 0) { exit(-2); } else if (pid2 == 0) { pause(); kill(pid, SIGUSR2); printf("signal sent to first child\n"); } else { printf("this is the parent\n"); kill(pid2, SIGUSR1); printf("signal sent to second child\n"); wait(NULL); printf("waiting for second child\n"); wait(NULL); printf("waited for both\n"); // 补全换行,确保输出及时刷新 exit(-3); } } }
修复说明
- 修正
write的长度参数,用strlen获取准确长度,彻底避免越界问题。 - 替换
signal为sigaction,消除跨平台行为差异带来的隐患。 - 在父进程最后一行
printf添加换行符,保证输出能及时刷新到终端。
修复后,第二个子进程可正常执行kill(pid, SIGUSR2),第一个子进程收到信号后会立即执行exit(0)终止,不会走到sleep(100)和printf("error\n")。
内容的提问来源于stack exchange,提问作者scanpower
相关产品推荐
相关产品推荐

