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

mjs*_*ort 5 linux concurrency pid exit-code return-code

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

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

下面的 bash 脚本示例:

local file=$1
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
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 5

子进程的PID重用变为可用时,父进程调用waitwaitpid(或家庭等任何其他功能wait3wait4等等)。

当子进程死亡时,它会像僵尸一样留在后面——进程表中的一个条目,后面没有进程,它留在后面只是为了保留进程 ID 并存储退出状态。调用waitpid阻塞直到指定的子进程死亡(或者如果它已经死亡则立即返回),检索子进程的状态代码,并获得僵尸(即删除进程表条目,释放进程 ID 以供重用)。调用wait是类似的,但只要一个子进程死了就返回。

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

如果父进程在子进程之前死亡,则子进程被称为 init 收养的孤儿,PID 为 1 的进程。 init 工作的一部分是收割孤儿。

在 shell 脚本中,wait内置 with 是wait系统调用的包装器。如果脚本有多个子进程,在所有子进程都死wait之前没有参数块,并且wait在所有指定的进程都死之前有一些参数块(没有办法等到一个进程死了而不指定哪个进程)。如果wait $pid1返回,则可能$pid2已经死亡并已被另一个进程重用;但是,$pid2即使如此,shell也会跟踪的状态代码,后续wait $pid2将返回其状态代码。但是,在此之前您不应分叉新的后台作业,以避免在$pid2被重用于后台作业时造成混淆。