
LinuxオペレーティングシステムでPIDを再利用できますか?
たとえば、PID名は2252です。 PIDは無効になり、カーネルプロセステーブルから削除されます。プロセステーブルは新しいプロセスに同じPIDを再利用できますか?それとも、将来のプロセスでは使用されませんか?
答え1
確かに。それ以外の場合、システムは起動時に32768プロセス(またはシステムの最大PID数)のみを実行できます。
プロセスが終了して待機している限り(親または子reaperによって、または親プロセスが終了した場合initによって)、そのpidは再利用できます。
スクリプトが次のことを行うことがわかります。
cmd1 & pid1=$!
something else
cmd2 & pid2=$!
more things
kill "$pid1" "$pid2"
シェル(ほとんどのシェル)言語は、子プロセスを処理するためのより良いAPIを提供しないため、これはおおよそのものです。
これらのプロセスが終了した場合、以前に開始されたプロセスが引き続き参照されるという$pid1
保証はありません。また、同じかもしれません(最初にすでに死んだ場合)。その結果、誤ったプロセスが終了する可能性があります。$pid2
$pid1
$pid2
cmd1
cmd2
kill
実際、これはほとんど問題ではありません。特に、pidが順次割り当てられるシステムでは、pid番号をラップするのにかなりの時間がかかるからです。ただし、pidテーブルがいっぱいになると(ゾンビプロセスがいっぱいになると)、一部の攻撃者はそれを悪用する可能性があります。
答え2
はい、再利用できます。 Stéphane Chazelasの回答に追加すると、次のようになります。
たとえば、スクリプトにこれが必要な場合は、kill $PID
$ PID一つ子プロセスで正しいプロセスを終了しているかどうかわからない場合は、少なくともbashは、次のように$ PIDを持つプロセスが現在のシェルの子であることを確認できます。
if grep -qFx $PID <(jobs -rp); then
kill $PID
fi
これはjobs -rp
subPIDを印刷し、grep -qFx $PID
$ PIDが一致した場合は0を返します。
差別化が必要なとき一つ他のシステムプロセスの子プロセスです。しかし、区別したい場合多くの種類現在のシェルの子について、各子が終了したときに現在のシェルに通知したい場合があります。たとえば、
{
trap "echo $BASHPID >> exited" EXIT
# some long action
} &
ここで子プロセスが終了すると、そのPIDがファイルに書き込まれますexited
。メインプロセスは、特定のPIDを持つプロセスが終了する前に終了したことを確認できます。
メモ。子プロセスが終了するたびに、SIGCHLD信号が現在のシェルに送信されます。これはプロセスを最適化するために使用できます(例trap "something..." SIGCHLD
:)