Linux 中 PID 重用的可能性

Linux 中 PID 重用的可能性

在Linux操作系统中,PID有可能被重用吗?

例如,一个 PID 名为 2252。该 PID 已失效并从内核进程表中删除。进程表是否有可能为新进程重新使用相同的 PID,或者它不会在任何即将到来的进程中使用?

答案1

当然。否则,系统每次启动只能运行 32768 个进程(或系统上的最大 pid 号)。

只要一个进程死亡并已被等待(如果父进程死亡,则由其父进程或子子收割者或 init 等待),其 pid 就可以重用。

您会看到脚本执行以下操作:

cmd1 & pid1=$!
something else
cmd2 & pid2=$!
more things
kill "$pid1" "$pid2"

这些是近似值,因为 shell(大多数 shell)语言没有为您提供任何更好的 API 来处理子进程。

如果这些进程可能已经死亡,则不能保证$pid1和/或$pid2仍会引用较早启动的进程。$pid1并且$pid2也可能是相同的(如果在开始cmd1时已经死亡)。cmd2所以kill可能会杀死错误的进程。

实际上,这很少会成为问题,特别是在按顺序分配 pid 的系统上,因为 pid 数字需要相当长的时间才能换行。但当 pid 表变满时(例如当它充满僵尸进程时),一些攻击者可以利用这一点。

答案2

是的,可以重复使用。只是补充一下 Stéphane Chazelas 的答案:

如果您需要这个来编写脚本,例如您想要kill $PID$PID 是单身的子进程,并且您不确定是否正在杀死正确的进程,那么至少在 bash 中您可以检查具有某些 $PID 的进程是否是当前 shell 的子进程,如下所示:

if grep -qFx $PID <(jobs -rp); then
   kill $PID
fi

这里jobs -rp打印子 PID,并grep -qFx $PID在 $PID 匹配时返回 0。

当您需要区分单身的来自其他系统进程的子进程。但如果你想区分多种的对于当前 shell 的子级,您可能需要在每个子级退出时通知当前 shell。例如:

{
    trap "echo $BASHPID >> exited" EXIT
    # some long action
} &

这里,当子进程退出时,它将其PID写入文件exited。主进程可以在杀死具有特定 PID 的进程之前检查它是否已经退出。

笔记。每次子进程退出时,SIGCHLD 信号都会发送到当前 shell。这可用于优化流程(例如trap "something..." SIGCHLD

相关内容