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
应该立即返回子进程的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
答案 0 :(得分:2)
我终于发现在lsof深度跟踪期间有一些fd泄漏。
fd泄漏修复后,问题就消失了。
答案 1 :(得分:1)
在我看来,waitpid并没有立即返回子pid,因为该进程不可用。
此外,看起来您实际上希望您的代码执行此操作,因为您使用waitpid()
选项指定NOHANG
,这可以防止阻塞,基本上允许父级继续运行,如果子级pid是不可用。
也许你的过程使用的是你没想过的东西?你可以追踪它的活动,看看你是否找到了瓶颈?
这是一个非常有用的链接,可以帮助您: http://infohost.nmt.edu/~eweiss/222_book/222_book/0201433079/ch08lev1sec6.html
答案 2 :(得分:0)
你可以简单地使用
for (;;) {
pid_t wpid = waitpid(-1, &sig, 0);
if (wpid > 0) break;
if (wpid < 0) print("wait error: %s\n", strerror(errno));
}
而不是睡一会儿,然后再试一次。