我有一个主进程(run-jobs
如下),它启动其他作业作为其子进程。当主进程失败(例如数据库失败)时,它会以非0状态码退出,这很好,并且可以通过查看$?
变量(echo $?
)来验证。
但是,我还想检查子流程的退出代码,以防主作业失败。一旦主进程消失,是否有一种方便的方法来检查以下process_1
退出代码?process_2
这是以下的简化输出ps auxf
:
vagrant 5167 | \_ php app/console run-jobs vagrant 5461 | \_ php process_1 vagrant 5517 | \_ php process_2
答案1
进程向其父进程报告其退出状态,如果其父进程对于 id 1 ( init
) 的进程已死亡,但对于最新版本的 Linux(3.4 或更高版本),您可以指定另一个祖先作为儿童副收割者对于该角色(使用prctl(PR_SET_CHILD_SUBREAPER)
)。
实际上,进程死亡后,就会变成僵尸进程,直到其父进程(或init
)检索其退出状态(withwaitpid()
或 other)。
就您而言,您是说孩子们在(由于?)死亡后正在死亡run-jobs
。这意味着他们将向init
指定为子子收割者的进程报告其退出状态。
如果init
不记录这一点(通常不会),并且如果您不使用审核或流程记帐,则退出状态将丢失。
如果在最新版本的 Linux 上,您可以创建自己的子收割机来获取这些孤立进程的 pid 和退出状态。就像perl
:
$ perl -MPOSIX -le '
require "syscall.ph";
syscall(&SYS_prctl,36,1) >= 0 or die "cannot set subreaper: $!";
# example running 1 child and 2 grand children:
if (!fork) {
# There, you would run:
# exec("php", "run-jobs");
if (!fork) {exec "sleep 1; exit 12"};
if (!fork) {exec "sleep 2; exit 123"};
exit(88)
}
# now reporting on all children and grand-children:
while (($pid = wait) > 0) {
print "$pid: " . WEXITSTATUS($?)
}'
22425: 88
22426: 12
22427: 123
如果您想要检索有关死亡进程的信息(例如命令行、用户、ppid……),您需要在它们仍处于僵尸状态时执行此操作,也就是在wait()
对它们执行任何操作之前。
为此,您需要使用waitid()
带有选项的 API (然后从命令WNOWAIT
获取信息)。我不认为有一个接口,所以你需要用另一种语言来编写它,比如./proc
ps
perl
C