Linux ゾンビ プロセスは、かなり前に停止したプロセスですが、まだプロセス テーブル内の位置を占めています。子プロセスが停止したときに親プロセスに wait() がない場合、通常はそれが表示されるのを確認できます。 "
" としてゾンビ プロセスを生成します。大量のゾンビ プロセスが生成されると、使用可能なプロセス番号がないため、システムは新しいプロセスを生成できなくなります。そのため、ゾンビ プロセスは回避する必要があります。
このチュートリアルの動作環境: 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 サイトの他の関連記事を参照してください。

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

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

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

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

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

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

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

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


ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

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

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

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

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

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境
