" としてゾンビ プロセスが生成されます。大量のゾンビ プロセスが生成されると、使用可能なプロセス番号がないため、システムは新しいプロセスを生成できなくなるため、ゾンビ プロセスは回避する必要があります。"/> " としてゾンビ プロセスが生成されます。大量のゾンビ プロセスが生成されると、使用可能なプロセス番号がないため、システムは新しいプロセスを生成できなくなるため、ゾンビ プロセスは回避する必要があります。">
検索
ホームページ運用・保守Linuxの運用と保守Linux ゾンビプロセスとは何ですか?

Linux ゾンビプロセスとは何ですか?

Apr 06, 2023 am 11:37 AM
linuxゾンビプロセス

Linux ゾンビ プロセスは、かなり前に停止したプロセスですが、まだプロセス テーブル内の位置を占めています。子プロセスが停止したときに親プロセスに wait() がない場合、通常はそれが表示されるのを確認できます。 " " としてゾンビ プロセスを生成します。大量のゾンビ プロセスが生成されると、使用可能なプロセス番号がないため、システムは新しいプロセスを生成できなくなります。そのため、ゾンビ プロセスは回避する必要があります。

Linux ゾンビプロセスとは何ですか?

このチュートリアルの動作環境: linux5.9.8 システム、Dell G3 コンピューター。

Linux におけるゾンビ プロセス (無効なプロセス) の生成と回避

#​​##1. ゾンビ プロセスとは

UNIX システムでは、プロセスは終了しますが、その親プロセスは終了します。プロセスが彼を待機しない (wait/waitpid を呼び出す) と、彼はゾンビ プロセスになります。 ps コマンドを使用してプロセスの実行ステータスを観察すると、これらのプロセスのステータス バーが表示されないことがわかります。ゾンビ プロセスは、ずっと前に停止しましたが、プロセス テーブル内のスロットをまだ占有しているプロセスです。

ただし、プロセスの親プロセスが先に終了していれば、そのプロセスはゾンビプロセスにはなりません。各プロセスが終了すると、システムは現在のシステムで実行中のすべてのプロセスをスキャンして、終了したプロセスの子プロセスであるかどうかを確認し、子プロセスである場合は、Init プロセスがそれを引き継ぎ、親プロセスになります。したがって、各プロセスが親プロセスを持つことが保証されます。 Init プロセスは子プロセスを自動的に待機するため、Init によって引き継がれたすべてのプロセスがゾンビ プロセスになることはありません。

2. UNIX でのプロセスの動作方法

各 Unix プロセスにはプロセス テーブルのエントリ ポイント (エントリ) があり、

コア プロセスプロセスの実行時に使用され、受信されるすべての情報エントリポイントに保存されます。 ps コマンドを使用してシステム内のプロセス情報を表示すると、プロセス テーブル内の関連データが表示されます。 fork() システム コールで新しいプロセスが作成されると、コア プロセスはプロセス テーブル内の新しいプロセスにエントリ ポイントを割り当て、エントリ ポイントに対応するプロセス テーブルに関連情報を格納します。これらの情報の 1 つは、親プロセスの識別番号です。

子プロセスの終了と親プロセスの実行は非同期プロセスです。つまり、親プロセスは子プロセスがいつ終了するかを予測できません。それでは、親プロセスがビジーすぎて子プロセスを待つことができないため、または子プロセスがいつ終了するかわからないため、子プロセスが終了したときのステータス情報は失われるのでしょうか?

それはできません。 UNIX には、子プロセスの終了時に親プロセスがステータス情報を知りたい限り、それを取得できるメカニズムが用意されているためです。このメカニズムは次のとおりです。子プロセスがライフサイクルを完了すると、exit() システムコールが実行され、カーネルは開いているファイル、占有メモリなどを含むプロセスのすべてのリソースを解放します。ただし、特定の情報 (プロセス ID、終了コード、プロセスの終了ステータス、プロセスにかかった CPU 時間など) は引き続き保持され、これらのデータはシステムがパスするまで保持されます。それを親プロセスに送信し、親プロセスが wait/waitpid 経由でフェッチするまで解放しません。

言い換えれば、プロセスが終了しても、プロセスは完全に消滅するわけではありません。プロセスは終了し、実行されなくなりますが、親プロセスが再利用するのを待っている残りのデータがまだ残っています。親プロセスが子プロセスを forks() する場合、wait() (または waitpid()) を使用して子プロセスが終了するのを待つ必要があります。子プロセスの残存データを消去するのは、この wait() アクションです。

3. ゾンビプロセスの害

親プロセスがwait/waitpidを呼ばないと、保持している情報は解放されず、プロセス番号は常に占有されますが、システムはプロセステーブルの容量には限りがあり、使用できるプロセス番号も限られているため、ゾンビプロセスが大量に生成されると、使用可能なプロセス番号がなくなり、新たなプロセスを生成できなくなります。

したがって、無効なプロセスはシステムのメモリ リソースを占有し、システムのパフォーマンスに影響を与えるだけでなく、その数が多すぎるとシステムの麻痺を引き起こすこともあります。また、スケジューラは Defunct プロセスを選択できないため、kill コマンドで Defunct プロセスを削除することはできず、システムを再起動するしか方法がありません。

4. ゾンビプロセスの生成

子プロセスが終了したときに親プロセスに wait() がない場合、通常は ps を使用して「
子プロセスが終了した後、親プロセスがデータを読み取る前に、無効なプロセスが表示されることがわかります。これを利用して、次のプログラムを使用して、無効なプロセスを作成できます:

#include <stdio.h> 
 
#include<sys> 
 
main()  
{  
 
 if(!fork())  
    {  
 
        printf(“child pid=%d\n”, getpid());  
 
        exit(0);  
 
    }  
 
    sleep(20);  
 
    printf(“parent pid=%d \n”, getpid());  
 
    exit(0);  
 
}</sys></stdio.h>

当上述程序以后台的方式执行时,第17行强迫程序睡眠20秒,让用户有时间输入ps -e指令,观察进程的状态,我们看到进程表中出现了defunct进程。当父进程执行终止后,再用ps -e命令观察时,我们会发现defunct进程也随之消失。这是因为父进程终止后,init 进程会接管父进程留下的这些“孤儿进程”(orphan process),而这些“孤儿进程”执行完后,它在进程表中的进入点将被删除。如果一个程序设计上有缺陷,就可能导致某个进程的父进程一直处于睡眠状态或是陷入死循环,父进程没有wait子进程,也没有终止以使Init接管,该子进程执行结束后就变成了defunct进程,这个defunct 进程可能会一直留在系统中直到系统重新启动。

在看一个产生僵尸进程的例子。

子进程要执行的程序test_prog

//test.c 
#include <stdio.h> int main()  {  
 int i = 0;  
 for (i = 0 ; i </stdio.h>

父进程father的代码father.c

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
int main()  
{  
 int pid = fork ();  
 if (pid == 0)  
        {  
                system ("./test_prog");  
                _exit (0);  
        }else 
        {  
 int i = 0;  
 /* 
                                int status = 0; 
                while (!waitpid(pid, &status, WNOHANG)) 
                { 
                        printf ("father waiting%d\n", ++i); 
                        sleep (1); 
                }*/ 
 while (1)  
                {  
                        printf ("father waiting over%d\n", ++i);  
                        sleep (1);  
                }  
 return 0;  
        }  
 
}

执行./father,当子进程退出后,由于父进程没有对它的退出进行关注,会出现僵尸进程

20786 pts/0    00:00:00 father  
20787 pts/0    00:00:00 father <defunct></defunct>

总结:子进程成为 defunct 直到父进程 wait(),除非父进程忽略了 SIGCLD 。更进一步,父进程没有 wait() 就消亡(仍假设父进程没有忽略 SIGCLD )的子进程(活动的或者 defunct)成为 init 的子进程,init 着手处理它们。

五、如何避免僵尸进程

1、父进程通过wait和waitpid等函数等待子进程结束,这会导致父进程挂起。

在上个例子中,如果我们略作修改,在第8行sleep()系统调用前执行wait()或waitpid()系统调用,则子进程在终止后会立即把它在进程表中的数据返回给父进程,此时系统会立即删除该进入点。在这种情形下就不会产生defunct进程。

2. 如果父进程很忙,那么可以用signal函数为SIGCHLD安装handler。在子进程结束后,父进程会收到该信号,可以在handler中调用wait回收。

3. 如果父进程不关心子进程什么时候结束,那么可以用signal(SIGCLD, SIG_IGN)或signal(SIGCHLD, SIG_IGN)通知内核,自己对子进程的结束不感兴趣,那么子进程结束后,内核会回收,并不再给父进程发送信号

4. fork两次,父进程fork一个子进程,然后继续工作,子进程fork一个孙进程后退出,那么孙进程被init接管,孙进程结束后,init会回收。不过子进程的回收还要自己做。 下面就是Stevens给的采用两次folk避免僵尸进程的示例:

#include "apue.h" #include <sys>  int main(void)  ...{  
     pid_t    pid;  
 
 if ((pid = fork())  0)  
             exit(0);    /**//* parent from second fork == first child */ 
 /**//* 
          * We're the second child; our parent becomes init as soon 
          * as our real parent calls exit() in the statement above. 
          * Here's where we'd continue executing, knowing that when 
          * we're done, init will reap our status. 
         */ 
         sleep(2);  
         printf("second child, parent pid = %d ", getppid());  
         exit(0);  
     }  
 
 if (waitpid(pid, NULL, 0) != pid)  /**//* wait for first child */ 
         err_sys("waitpid error");  
 
 /**//* 
      * We're the parent (the original process); we continue executing, 
      * knowing that we're not the parent of the second child. 
     */ 
     exit(0);  }</sys>

相关推荐:《Linux视频教程

以上がLinux ゾンビプロセスとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
Linuxの5つの柱:彼らの役割を理解するLinuxの5つの柱:彼らの役割を理解するApr 11, 2025 am 12:07 AM

Linuxシステムの5つの柱は次のとおりです。1。Kernel、2。SystemLibrary、3。Shell、4。FileSystem、5。SystemTools。カーネルはハードウェアリソースを管理し、基本的なサービスを提供します。システムライブラリは、アプリケーション用の事前コンパイルされた機能を提供します。シェルは、ユーザーがシステムと対話するインターフェイスです。ファイルシステムはデータを整理して保存します。また、システムツールはシステム管理とメンテナンスに使用されます。

Linuxメンテナンスモード:ツールとテクニックLinuxメンテナンスモード:ツールとテクニックApr 10, 2025 am 09:42 AM

Linux Systemsでは、起動時に特定のキーを押すか、「sudosystemctlrescue」などのコマンドを使用することにより、メンテナンスモードを入力できます。メンテナンスモードを使用すると、管理者は、ファイルシステムの修復、パスワードのリセット、セキュリティの脆弱性など、干渉なしにシステムメンテナンスとトラブルシューティングを実行できます。

主要なLinux操作:初心者向けガイド主要なLinux操作:初心者向けガイドApr 09, 2025 pm 04:09 PM

Linuxの初心者は、ファイル管理、ユーザー管理、ネットワーク構成などの基本操作をマスターする必要があります。 1)文件管理:使用mkdir、タッチ、ls rm 3)ネットワーク構成:ifconfig、echo、およびufwコマンドを使用します。これらの操作はLinuxシステム管理の基礎であり、それらをマスターすることでシステムを効果的に管理できます。

sudoを使用して、Linuxのユーザーに高い特権を付与するにはどうすればよいですか?sudoを使用して、Linuxのユーザーに高い特権を付与するにはどうすればよいですか?Mar 17, 2025 pm 05:32 PM

この記事では、LinuxのSudo特権を管理する方法について説明します。重要な焦点は、 /etc /sudoersの安全性とアクセスを制限することです。

LinuxでSSHに2要素認証(2FA)を実装するにはどうすればよいですか?LinuxでSSHに2要素認証(2FA)を実装するにはどうすればよいですか?Mar 17, 2025 pm 05:31 PM

この記事では、Google Authenticatorを使用してLinux上のSSH用の2要素認証(2FA)のセットアップ、インストール、構成、およびトラブルシューティング手順の詳細に関するガイドを提供します。 Enhanced Secなど、2FAのセキュリティ利益を強調しています

TOP、HTOP、VMSTATなどのツールを使用してLinuxのシステムパフォーマンスを監視するにはどうすればよいですか?TOP、HTOP、VMSTATなどのツールを使用してLinuxのシステムパフォーマンスを監視するにはどうすればよいですか?Mar 17, 2025 pm 05:28 PM

この記事では、Linuxシステムのパフォーマンスを監視するためにTop、HTOP、およびVMSTATを使用して、効果的なシステム管理のための独自の機能とカスタマイズオプションを詳述することについて説明します。

パッケージマネージャー(apt、yum、dnf)を使用してLinuxのソフトウェアパッケージを管理するにはどうすればよいですか?パッケージマネージャー(apt、yum、dnf)を使用してLinuxのソフトウェアパッケージを管理するにはどうすればよいですか?Mar 17, 2025 pm 05:26 PM

記事では、APT、Yum、およびDNFを使用してLinuxでソフトウェアパッケージの管理を行い、インストール、更新、および削除をカバーしています。さまざまな分布に対する機能と適合性を比較します。

パターンマッチングにLinuxで正規表現(正規表現)を使用するにはどうすればよいですか?パターンマッチングにLinuxで正規表現(正規表現)を使用するにはどうすればよいですか?Mar 17, 2025 pm 05:25 PM

この記事では、パターンマッチング、ファイル検索、テキスト操作、グレップ、SED、awkなどのツールの詳細、ファイル検索、テキスト操作のためにLinuxで正規表現(Regex)を使用する方法について説明します。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

SublimeText3 英語版

SublimeText3 英語版

推奨: Win バージョン、コードプロンプトをサポート!

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境