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

嵌入式Linux下fork子进程后waitpid获取返回值失败排查

问题分析与解决方案

首先,咱们来拆解你遇到的**ECHILD错误(errno=10)**的核心原因:你的代码在成功回收子进程后,仍然继续调用waitpid去等待同一个已经不存在的PID,这就导致系统返回"没有可等待的子进程"的错误。

代码逻辑漏洞拆解

看父进程的循环逻辑:

for (i = 0 ; i < 10 ; i++) {
    pid_t ws = waitpid(pid, &childExitStatus, WNOHANG);
    if (-1 == ws) {
        DEBUG_PRINT("parent - failed wait. errno = %d", errno);
        return -1;
    }
    if (0 == ws) {
        DEBUG_PRINT("parent - child is still running");
        sleep(1);
        continue;
    }
    // 这里缺失了关键步骤:成功获取子进程状态后没有终止循环!
}

结合你的运行输出,实际流程是这样的:

  1. 子进程sleep(2)期间,父进程前两次循环(i=0、1)调用waitpid返回0,提示子进程仍在运行;
  2. 当i=2时,子进程已经执行exit(1),此时waitpid成功返回子进程PID,获取到退出状态,但代码没有终止循环;
  3. 进入i=3的循环,再次调用waitpid等待同一个PID——但该子进程已经被回收,系统直接返回ECHILD错误。

修复方案

只需要在waitpid成功获取子进程状态后,立即跳出循环,避免重复调用waitpid:

for (i = 0 ; i < 10 ; i++) {
    pid_t ws = waitpid(pid, &childExitStatus, WNOHANG);
    if (-1 == ws) {
        DEBUG_PRINT("parent - failed wait. errno = %d", errno);
        return -1;
    }
    if (0 == ws) {
        DEBUG_PRINT("parent - child is still running");
        sleep(1);
        continue;
    }
    // 成功获取子进程状态,跳出循环处理退出码
    break;
}

额外说明

你尝试的signal(SIGCHLD,SIG_DFL)或SIG_IGN之所以没用,是因为这个问题和SIGCHLD信号处理无关——既不是信号被忽略导致子进程变成僵尸,也不是信号处理函数干扰了wait操作,纯粹是循环逻辑的小漏洞。你提到的sigwait等方案确实没必要,修复循环逻辑就能完美解决问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:44:03