我将程序作为守护程序运行.
父进程仅等待子进程,当它意外死亡时,请分叉并再次等待.
for (; 1;) {
if (fork() == 0) break;
int sig = 0;
for (; 1; usleep(10000)) {
pid_t wpid = waitpid(g->pid[1], &sig, WNOHANG);
if (wpid > 0) break;
if (wpid < 0) print("wait error: %s\n", strerror(errno));
}
}
但是当子进程被-9信号杀死时,子进程进入僵尸进程.
waitpid应该立即返回子进程的pid!
但是waitpid在大约90秒后获得了pid号码,
cube 28139 0.0 0.0 70576 900 ? Ss 04:24 0:07 ./daemon -d
cube 28140 9.3 0.0 0 0 ? Zl 04:24 106:19 [daemon] <defunct>
这是父亲的痕迹
父亲没有被卡住,总是叫wait4.
strace -p 28139
Process 28139 attached - interrupt to quit
restart_syscall(<... resuming interrupted call ...>) = 0
wait4(28140, 0x7fff08a2681c, WNOHANG, NULL) = 0
nanosleep({0, 10000000}, NULL) = 0
wait4(28140, 0x7fff08a2681c, WNOHANG, NULL) = 0
大约90秒后,父亲得到了SIGCHILD,而wait4返回了死孩子的pid.
--- SIGCHLD (Child exited) @ 0 (0) ---
restart_syscall(<... resuming interrupted call ...>) = 0
wait4(28140, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGKILL}], WNOHANG, NULL) = 28140
为什么子进程不会立即退出?相反,它意外地变成了僵尸.
解决方法:
我终于发现在lsof的深度跟踪过程中有一些fd泄漏.
解决了FD泄漏后,问题解决了.