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

CSAPP信号程序测试问题:fork()执行后父进程无法从STDIN读取输入

问题原因
  • 信号处理函数阻塞主流程执行
    你在handler2末尾添加了sleep(1000)调用,信号处理函数执行期间会挂起主进程的正常执行逻辑。3个子进程退出会触发至少2次SIGCHLD信号处理,每次处理都会等待1000秒,此期间主流程的read调用一直被挂起,无法响应用户输入。
  • 未处理系统调用被中断的异常
    Ubuntu 16.04中signal函数注册信号处理函数时,默认不会开启SA_RESTART标志。read属于慢速系统调用,当它在阻塞等待输入时被SIGCHLD信号中断,会直接返回-1并将errno设置为EINTR,你当前的代码未对该错误做重试处理,会直接触发错误退出逻辑。
解决方案
  1. 删除信号处理函数中的sleep调用
    sleep不属于异步信号安全函数,且超长等待完全阻塞了主流程执行,直接删除handler1和handler2中的sleep(1000);语句即可。
  2. 为read调用添加EINTR重试逻辑
    修改read调用的判断逻辑,被信号中断时自动重试:
while ((n = read(STDIN_FILENO, buf, sizeof(buf))) < 0) {
    if (errno != EINTR) {
        unix_error("read");
    }
    // 被信号中断,重试读取
}
  1. (可选)使用sigaction注册信号并开启系统调用自动重启
    如果希望被信号中断的慢速系统调用自动恢复执行,可以用sigaction代替signal注册处理函数,开启SA_RESTART标志:
struct sigaction sa;
sa.sa_handler = handler2;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL) == -1) {
    unix_error("sigaction error");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 19:54:04