You need to enable JavaScript to run this app. C++中SIGCHLD设为SIG_IGN导致system调用返回错误的原因与解决
优惠活动
大模型
产品
解决方案
定价
更多

C++中SIGCHLD设为SIG_IGN导致system调用返回错误的原因与解决

问题原因

system函数的核心实现逻辑分为三步:

  1. 父进程调用fork()创建子进程
  2. 子进程调用exec()执行传入的shell命令
  3. 父进程调用waitpid()阻塞等待子进程退出,获取退出状态作为返回值

当你调用signal(SIGCHLD, SIG_IGN)显式将SIGCHLD信号的处理逻辑设置为忽略时,POSIX标准规定系统内核会自动回收退出的子进程资源,不会留下僵尸进程,也不会再向父进程发送SIGCHLD信号。这就导致执行pwd的子进程退出后直接被内核销毁,system内部第三步的waitpid()调用找不到对应的子进程,就会返回-1,同时设置errno为ECHILD(值为10,含义是当前进程没有可等待的子进程)。

你看到pwd有正常路径输出,说明子进程确实执行成功了,只是system函数因为无法获取子进程退出状态才返回了错误值。

规避方案
  • 方案1:不全局设置SIGCHLD为SIG_IGN,改为自定义SIGCHLD信号处理函数,在函数内部调用waitpid()回收僵尸进程。这种方式不会影响system内部的waitpid()逻辑,返回值会恢复正常。
  • 方案2:调用system前临时保存SIGCHLD的处理配置,调用完成后恢复。示例代码如下:
// 保存旧的信号处理配置
struct sigaction old_act;
sigaction(SIGCHLD, NULL, &old_act);
// 临时设置为默认处理
signal(SIGCHLD, SIG_DFL);

// 执行system调用
int ret = system("pwd");

// 恢复原来的信号处理配置
sigaction(SIGCHLD, &old_act, NULL);
  • 方案3:自行实现类似system的逻辑,通过fork()+exec()+自定义等待逻辑完成命令调用,完全自主控制子进程回收流程,不受全局SIGCHLD配置影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 22:21:01