Linux ゾンビプロセスとは何ですか?
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/types.h> main() { if(!fork()) { printf(“child pid=%d\n”, getpid()); exit(0); } sleep(20); printf(“parent pid=%d \n”, getpid()); exit(0); }<div class="highlight"> <p data-pid="Y1zLLGu8">当上述程序以后台的方式执行时,第17行强迫程序睡眠20秒,让用户有时间输入ps -e指令,观察进程的状态,我们看到进程表中出现了defunct进程。当父进程执行终止后,再用ps -e命令观察时,我们会发现defunct进程也随之消失。这是因为父进程终止后,init 进程会接管父进程留下的这些“<strong>孤儿进程</strong>”(orphan process),而这些“孤儿进程”执行完后,它在进程表中的进入点将被删除。如果一个程序设计上有缺陷,就可能导致某个进程的父进程一直处于睡眠状态或是陷入死循环,父进程没有wait子进程,也没有终止以使Init接管,该子进程执行结束后就变成了defunct进程,这个defunct 进程可能会一直留在系统中直到系统重新启动。</p> <p data-pid="e4bzxqVS">在看一个产生僵尸进程的例子。</p> <p data-pid="oyygQagx">子进程要执行的程序test_prog</p> <div class="highlight"><pre class="brush:php;toolbar:false">//test.c #include <stdio.h> int main() { int i = 0; for (i = 0 ; i < 10; i++) { printf ("child time %d\n", i+1); sleep (1); } return 0; }
父进程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 直到父进程 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/wait.h> int main(void) ...{ pid_t pid; if ((pid = fork()) < 0) ...{ err_sys("fork error"); } else if (pid == 0) ...{ /**//* first child */ if ((pid = fork()) < 0) err_sys("fork error"); else if (pid > 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); }
相关推荐:《Linux视频教程》
以上がLinux ゾンビプロセスとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ホットAIツール

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

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

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

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

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

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

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

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Centosとubuntuの重要な違いは次のとおりです。起源(CentosはRed Hat、for Enterprises、UbuntuはDebianに由来します。個人用のDebianに由来します)、パッケージ管理(CentosはYumを使用し、安定性に焦点を当てます。チュートリアルとドキュメント)、使用(Centosはサーバーに偏っています。Ubuntuはサーバーやデスクトップに適しています)、その他の違いにはインストールのシンプルさが含まれます(Centos is Thin)

Centosは廃止されました、代替品には次のものが含まれます。1。RockyLinux(最高の互換性)。 2。アルマリン(Centosと互換性); 3。Ubuntuサーバー(設定が必要); 4。RedHat Enterprise Linux(コマーシャルバージョン、有料ライセンス); 5。OracleLinux(CentosとRhelと互換性があります)。移行する場合、考慮事項は次のとおりです。互換性、可用性、サポート、コスト、およびコミュニティサポート。

Centosのインストール手順:ISO画像をダウンロードし、起動可能なメディアを燃やします。起動してインストールソースを選択します。言語とキーボードのレイアウトを選択します。ネットワークを構成します。ハードディスクをパーティション化します。システムクロックを設定します。ルートユーザーを作成します。ソフトウェアパッケージを選択します。インストールを開始します。インストールが完了した後、ハードディスクから再起動して起動します。

Dockerデスクトップの使用方法は? Dockerデスクトップは、ローカルマシンでDockerコンテナを実行するためのツールです。使用する手順には次のものがあります。1。Dockerデスクトップをインストールします。 2。Dockerデスクトップを開始します。 3。Docker Imageを作成します(DockerFileを使用); 4. Docker画像をビルド(Docker Buildを使用); 5。Dockerコンテナを実行します(Docker Runを使用)。

DockerはLinuxカーネル機能を使用して、効率的で孤立したアプリケーションランニング環境を提供します。その作業原則は次のとおりです。1。ミラーは、アプリケーションを実行するために必要なすべてを含む読み取り専用テンプレートとして使用されます。 2。ユニオンファイルシステム(UnionFS)は、違いを保存するだけで、スペースを節約し、高速化する複数のファイルシステムをスタックします。 3.デーモンはミラーとコンテナを管理し、クライアントはそれらをインタラクションに使用します。 4。名前空間とcgroupsは、コンテナの分離とリソースの制限を実装します。 5.複数のネットワークモードは、コンテナの相互接続をサポートします。これらのコア概念を理解することによってのみ、Dockerをよりよく利用できます。

Dockerプロセス表示方法:1。DockerCLIコマンド:Docker PS; 2。SystemDCLIコマンド:SystemCTL Status Docker; 3。CLIコマンドを作成するDocker:Docker-Compose PS。 4。プロセスエクスプローラー(Windows); 5。 /procディレクトリ(Linux)。

VSコードシステムの要件:オペレーティングシステム:オペレーティングシステム:Windows 10以降、MACOS 10.12以上、Linux Distributionプロセッサ:最小1.6 GHz、推奨2.0 GHz以上のメモリ:最小512 MB、推奨4 GB以上のストレージスペース:最低250 MB以上:その他の要件を推奨:安定ネットワーク接続、XORG/WAYLAND(Linux)

障害のあるDocker画像ビルドのトラブルシューティング手順:DockerFileの構文と依存関係バージョンを確認します。ビルドコンテキストに必要なソースコードと依存関係が含まれているかどうかを確認します。エラーの詳細については、ビルドログを表示します。 -targetオプションを使用して、階層フェーズを構築して障害点を識別します。 Dockerエンジンの最新バージョンを使用してください。 -t [image-name]:デバッグモードで画像を作成して、問題をデバッグします。ディスクスペースを確認し、十分であることを確認してください。 Selinuxを無効にして、ビルドプロセスへの干渉を防ぎます。コミュニティプラットフォームに助けを求め、DockerFilesを提供し、より具体的な提案のためにログの説明を作成します。
