殺せないゾンビプロセスに遭遇した




1.ゾンビのプロセスを知る


1.ゾンビプロセスはどのようにして生まれましたか?

プロセスの実行中は、親プロセスといくつかの子プロセスが生成されます。
子プロセスが実行されると、Exitシグナルを送信して終了し、その親プロセスが(wait / waitpid)を呼び出して終了を読み取ります。ステータス、
読み取りが成功した場合、子プロセスはプロセステーブルから削除されます。
そうでない場合、プロセステーブルから削除できず、ゾンビプロセスになります。

psコマンドを使用してプロセスのステータスを監視すると、これらのプロセスのステータスが無効になっていることがわかります。
ps aux {2} grep Z


2.ゾンビプロセスは有害ですか?

ゾンビプロセスの数が膨大で長期間存在する場合、それはプロセステーブルに残っている大量のゾンビプロセス情報に相当し、
この情報をメモリに保存する必要があるため、リソースを浪費します。




第二に、ゾンビプロセスの従来の殺害方法


1.-9個の親プロセスpidを強制終了します

ゾンビプロセスが停止し(task_struct構造体のみが保持され)、停止したプロセスを直接強制終了できないため、
ゾンビプロセスは通常、親プロセスを強制終了することによって間接的に強制終了されます。

親プロセスを強制終了すると、ゾンビプロセスは孤立したプロセスになり、最初のプロセスに採用されます。最初のプロセスは、その名前で子プロセスをスキャンし、Z状態のプロセスを再利用します。

ps -ef  | grep 66046
qtest    66046      12321  99 Apr07 ?        992-23:20:31 [kvsvr] <defunct>

kill -9  12321

2.オペレーショナルリスクのリマインダー

親プロセスを強制終了する前に、オペレーショナルリスクを評価し、親プロセスに関連付けられている他のプロセスが強制終了に耐えられるかどうかを確認することをお勧めします。




第三に、ゾンビプロセスの暴力的な殺害方法


1.再起動

ゾンビプロセスの親プロセスがプロセスNo.1(ppid = 1)の場合、

ps -ef  | grep 66046
qtest    66046      1  99 Apr07 ?        992-23:20:31 [kvsvr] <defunct>

したがって、killは機能しなくなり、解決するためにサーバー再起動することしかできません


2.オペレーショナルリスクのリマインダー


起動は比較的簡単で失礼ですが、効果的です。上記のサービスが再起動の影響に耐えられるかどうかに基づいて、再起動によって解決できるかどうかを判断することをお勧めします。




4.ゾンビプロセスのppidが1になるのはなぜですか?


1.理論的には、Initが引き継いだプロセスはゾンビにはなりません

各プロセスの終了時に、システムは現在のシステムで実行されているすべてのプロセスをスキャンして、
終了したばかりのプロセスの子プロセスであるプロセスがあるかどうか確認します。子プロセスの
場合は、Initプロセスがそれを引き継いで実行します。各プロセスに親プロセスがあることを確認するための親プロセス。


一般的に、
initプロセスがZ状態のプロセスを引き継ぐと、それをリサイクルする
ために待機が呼び出されます。したがって、理論的には、initによって引き継がれるすべてのプロセスがゾンビプロセスになるわけではありません。


では、なぜppid1のゾンビプロセスがあるのでしょうか。



2.可能性について推測してみてください

ゾンビプロセス「プロセス終了」の根本原因に戻るここで、可能性について推測する試みを次に示します。

カーネル関数do_exitは、プロセスの終了時に呼び出されます。この関数には、次の2つの主要なロジックがあります。

do_exit()
  ->exit_notify()
     -> do_notify_parent()

2.1親プロセスとして:子プロセスの新しい親プロセスを見つけます(存在する場合)**

終了するプロセスがマルチスレッドプロセスの場合は、子プロセスを自分の兄弟
スレッドに委託できます。そのようなスレッドがない場合は、initプロセスに委託できます。
つまり、initプロセスがそのトリックを実行します。


2.2子プロセスとして:自分でtask_structを解放するように親プロセスに通知します**

シングルスレッドプロセスの場合、このプロセスも比較的単純です
が、マルチスレッドプロセスの場合は、少し複雑
です。スレッドグループの
他のスレッドが親プロセスに通知できるのは、スレッドグループのメインスレッドのみであるためです。親プロセスは、ゾンビ状態に入るためにリソースを予約する必要さえありません。これは、release_task関数を直接呼び出してすべてのリソースを解放することによって行われます。

親プロセスは子プロセスのメインスレッドのみを認識するため、スレッドグループでは、メインスレッドが終了しても、スレッドグループで実行されている他のスレッドがある場合、親プロセスはそれ自体のtask_structを解放するように通知されません。スレッドグループまで最後のスレッドが終了したときにのみ解放されます。

したがって、ユーザーモードでは、pthread_exitを呼び出してメインスレッドを最初に終了させることができますが、カーネルモードでは、スレッドグループで実行されている他のスレッドがあるため、メインスレッドのtask_structを保持する必要があります。この場合、メインスレッドはZゾンビ状態になり、initがメインスレッドを引き継いだとしても変化しません。


つまり、「ゾンビプロセス」のppidが1であるという現象。

おすすめ

転載: blog.csdn.net/weixin_44648216/article/details/111877287