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)); } }
waitpid
应该立即返回subprocess的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>
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
--- SIGCHLD (Child exited) @ 0 (0) --- restart_syscall(<... resuming interrupted call ...>) = 0 wait4(28140, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGKILL}], WNOHANG, NULL) = 28140
它在我看来像waitpid没有立即返回的孩子pid只是因为该进程不可用。
此外,它看起来像你实际上希望你的代码这样做,因为你指定了与NOHANG
选项的waitpid()
,这防止阻塞,基本上允许家长继续如果孩子PID不可用。
也许你的过程使用你没有想到的东西? 你可以跟踪它的活动,看看你是否找到了瓶颈?
这是一个非常有用的链接,可以帮助你: http : //infohost.nmt.edu/~eweiss/222_book/222_book/0201433079/ch08lev1sec6.html
我终于发现在lsof的深度追踪过程中有一些fd泄漏。
FD泄漏修复后,问题消失了。
你可以简单地使用
for (;;) { pid_t wpid = waitpid(-1, &sig, 0); if (wpid > 0) break; if (wpid < 0) print("wait error: %s\n", strerror(errno)); }
而不是睡一会儿再试一次。