誰かが、あなたがLinuxで親プロセスを殺したとき、その子は死ぬだろうと私に言った。
しかし、私はそれを疑います。それで、私は2つのbashスクリプトを書きました。ここで、father.sh
はchild.sh
を呼び出します
これが私のスクリプトです:
今私はbash father.sh
を実行します、あなたはそれをps -alf
で確認できます
次に、father.sh
をkill -9 24588
で強制終了し、子プロセスを終了する必要があると思いましたが、残念ながら間違っていました。
なぜ誰かが説明できますか?
tHX
いいえ、プロセスを一人で殺しても、子供は殺されません。
特定のグループのすべてのプロセスがシグナルを受信するようにする場合は、シグナルをプロセスグループに送信する必要があります。
kill -9 -parentpid
そうでない場合、3番目のスクリーンショットに示されているように、孤児はinit
にリンクされます(子のPPIDが1になっています)。
通常、親を殺すと子供も殺されます。
父親を殺した後も子供がまだ生きているのを見るのは、子供がSIGKILLイベントを処理することを選択した後にのみ死ぬためです。すぐに処理する必要はありません。スクリプトは、sleep()コマンドを実行しています。これは、スリープが完了するまで、ウェイクアップしてイベントを処理しません。
なぜPPID#1なのですか?親が死亡し、プロセステーブルに存在しません。 child.shはリンクではありません。実行中の親はありません。 initにリンクされていると言うと、何らかの形でinitを離れると、そのinitがプロセスのシャットダウンを制御できるという印象を与えます。また、親を殺すと祖父母が子供の所有者になるという印象も与えます。どちらも正しくありません。その子プロセスはまだプロセステーブルに存在し、実行されていますが、そのプロセスIDに基づく新しいイベントは、SIGKILLを処理するまで処理されません。これは、子供がゾンビ前であり、歩いて死んで、ラベル付けされる危険があることを意味します。
プロセスグループでの強制終了は異なり、プロセスグループ#によって兄弟および親を強制終了するために使用されます。また、「プロセスを強制終了する」とは、それ自体が「強制終了」ではなく、プロセスが破棄され、すべてのメモリが元に戻されなかった場合と同じように返されることを想定している点にも注意してください。それは処理するために多くの中で、特定のイベントをプロセスに送信するだけです。プロセスがそれを適切に処理しない場合、しばらくするとOSが表示され、強制的に「クリーンアップ」されます。
子(または親)が何かをディスクに書き込んで、I/Oが完了するのを待っているか、システムの安定性やファイルの整合性を損なう可能性のある他の重要なタスクを実行している可能性があるため、すぐには発生しません。
-bash:kill:(-123)-そのようなプロセスはありません
対話型のTerminal.appセッションでは、ジョブ制御/監視モードが有効になっている場合、フォアグラウンドプロセスグループID番号とバックグラウンドプロセスグループID番号は設計によって異なります。つまり、ジョブ制御が有効なTerminal.appセッションでコマンドをバックグラウンド化する場合、バックグラウンド化されたプロセスの_$!
_ pidは、実際には新しいプロセスグループID番号(pgid)です。
ただし、ジョブ制御が有効になっていないスクリプトでは、これが当てはまらない場合があります。バックグラウンドプロセスのpidは、新しいpgidではなく、通常のpidである可能性があります。これが、エラーメッセージ-bash: kill: (-123) - No such process
の原因です。プロセスグループを強制終了しようとしましたが、kill
コマンドに(pgidではなく)通常のpidのみを指定しています。
_# the following code works in Terminal.app because $! == $pgid
{
sleep 100 &
IFS=" " read -r pgid <<EOF
$(ps -p $! -o pgid=)
EOF
echo $$ $! $pgid
sleep 10
kill -HUP -- -$!
#kill -HUP -- -${pgid} # use in script
}
_
pkill -TERM -P <ProcessID>
これは親と子の両方を殺します