谁在等待 shell 后台进程?
Who waits for a shell background process?
我在想这个问题:
如果我在 bash
中键入以下命令
# 睡眠 100 &
shell怎么知道要等它结束?
当 shell fork 自身以执行 sleep 命令时,& 符号在技术上是否意味着它不会等待新 fork 的进程?
尽管如此,它仍然在等待它(否则我会把它看成僵尸,但我没有)
在这里感到困惑:\
shell 在其 child 进程退出时获得 SIGCHLD
;因此,它可以立即在信号处理程序中调用 wait4()
来获取它。
如果您 运行 strace bash
,您将看到如下内容:
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=13708, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG, NULL) = 13708
wait4(-1, 0x7fffbca63110, WNOHANG, NULL) = -1 ECHILD (No child processes)
也就是说: shell 得到一个 child 进程退出的信号;它在没有 PID 的情况下调用 wait4()
,从而从其进程 table 中收获第一个死亡的 child;并再次调用它,并被告知没有死者 children 仍然被收割。
这不同于进程在前台 运行 的情况,后者 阻塞 wait()
立即 运行。
我在想这个问题:
如果我在 bash
中键入以下命令# 睡眠 100 &
shell怎么知道要等它结束?
当 shell fork 自身以执行 sleep 命令时,& 符号在技术上是否意味着它不会等待新 fork 的进程? 尽管如此,它仍然在等待它(否则我会把它看成僵尸,但我没有)
在这里感到困惑:\
shell 在其 child 进程退出时获得 SIGCHLD
;因此,它可以立即在信号处理程序中调用 wait4()
来获取它。
如果您 运行 strace bash
,您将看到如下内容:
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=13708, si_status=0, si_utime=0, si_stime=0} ---
wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG, NULL) = 13708
wait4(-1, 0x7fffbca63110, WNOHANG, NULL) = -1 ECHILD (No child processes)
也就是说: shell 得到一个 child 进程退出的信号;它在没有 PID 的情况下调用 wait4()
,从而从其进程 table 中收获第一个死亡的 child;并再次调用它,并被告知没有死者 children 仍然被收割。
这不同于进程在前台 运行 的情况,后者 阻塞 wait()
立即 运行。