如果父进程仍然是 运行,子进程的 PID 是否可以重用?

Does the PID of a child process become available for reuse if the parent process is still running?

我 运行 在基于 *nix 的 OS 上,并且有一个脚本可以同时启动多个进程。我的主要目标是同时启动这些进程,并为每个进程收集返回的退出状态。我发现使用 wait(pid) 可以实现这一点,因为所有子进程都归父进程所有。但是,我担心一旦子进程(启动的并发进程之一)完成,其 PID 将被释放并可在系统内回收。

所以我猜想问题是,如果一个父进程同时启动多个子进程,那么完成的子进程的PID是否可以提供给系统回收prior到父进程完成?如果是这样,我怎样才能最好地获得每个子进程的退出状态?

下面的 bash 脚本示例:

local file=
local count=0
<files are split; and suffixed with aa,ab,ac,ad>

/home/text/concurrencyTest.sh $file-aa >> /home/text/$file-aa.log 2>&1 &
/home/text/concurrencyTest1.sh $file-ab >> /home/text/$file-ab.log 2>&1 &
/home/text/concurrencyTest2.sh $file-ac >> /home/text/$file-ac.log 2>&1 &
/home/text/concurrencyTest3.sh $file-ad >> /home/text/$file-ad.log 2>&1 &

for job in `jobs -p`
do
    echo "Job: $job"
    wait "$job"
    rc=$?
    echo "RC for $job is $rc"
    if [[ rc -ne 0 ]]; then
        FAIL[$count]="$job"
        ((count++))
    fi
done
if [[ $count -ne 0 ]]; then
    echo "ERROR: $count Job(s) Failed!"
    echo "Failed Process PID(s): ${FAIL[@]}"
    echo "Failed Processing for file: $file"
    return 1
fi

当 parent 进程调用 waitwaitpid(或该系列的任何其他函数,例如 wait3, wait4, 等等).

当 child 死亡时,它作为僵尸留在后面 — 进程 table 中的一个入口,后面没有进程,它留在后面只是为了保留进程 ID 并存储出口地位。调用 waitpid 阻塞直到指定的 child 进程死亡(或者如果它已经死亡则立即 returns),检索 child 的状态代码,并收获僵尸(即删除进程 table 条目,释放进程 ID 以供重用)。调用 wait 类似,但是 return 一个 child 进程结束后立即调用。

如果 parent 进程在进程死亡时忽略 SIGCHLD 信号,则进程不会变成僵尸进程,其 PID 立即可供重用。 parent 相对于 SIGCHLD 的状态在其他方面很重要;参见例如POSIX 详细信息。

如果 parent 进程在 child 之前死亡,则 child 被认为是 init 收养的孤儿,PID 为 1 的进程。它是 init 工作的一部分收获孤儿。

在 shell 脚本中,内置的 waitwait 系统调用的包装器。如果脚本有多个 children,wait 没有参数块,直到它们都死了,而 wait 有一些参数块,直到所有指定的进程都死了(没有办法等到一个进程死亡而不指定是哪个)。如果 wait $pid1 returns,则可能 $pid2 已经死亡并被另一个进程重用;然而,即使如此,shell 仍会跟踪 $pid2 的状态代码,随后的 wait $pid2 将 return 其状态代码。但是,在此之前您不应该创建新的后台作业,以避免混淆 $pid2 被重新用于后台作业。