Gu Dequan:個人のホームページ
個人コラム:「Linux オペレーティング システム」 「C/C++」 「LeedCode Question Writing」
キーボードはダメ、年収は100万!
前の記事ブログを読んで、プロセスの基本的な知識を簡単に理解しました。今日は 2 つの特別な知識を学習します。 . プロセス、ゾンビ プロセス、孤立したプロセス。
1. ゾンビプロセス
1. 関連概念
ゾンビ プロセスは、実行は終了したがプロセス テーブルにまだ存在するプロセスです。具体的には、プロセスが終了しても、その親プロセスは子プロセスの終了ステータス情報を収集するために wait または waitpid をすぐに呼び出さないため、子プロセスは終了したにもかかわらず、まだプロセス テーブル内の場所を占有しています。ゾンビプロセスが形成されます。ゾンビ プロセスは実際には比較的特殊な状態であり、瀕死状態 (Z ゾンビ) とも呼ばれます。プロセスの終了ステータスは維持する必要があります。プロセスは、それを気にするプロセス (親プロセス) に、与えられたタスクをどれだけうまく実行したかを伝える必要があるからです。実際のプログラミングでは、リソースが解放されていないゾンビプロセスの問題に注意する必要があります。 ps
コマンドを grep 'Z'
とともに使用すると、ステータス Z のすべてのプロセス、つまりゾンビ プロセスを検索できます。
2. ゾンビ状態
ゾンビは比較的特殊な状態です。プロセスが終了し、親プロセス (後述する wait() システム コールを使用) が子プロセス終了のリターン コードを読み取らない場合、ゾンビ (ゾンビ) プロセスが生成されます。ゾンビプロセスは終了状態でプロセステーブルに残り、親プロセスが終了ステータスコードを読み取るのを待っています。したがって、子プロセスが終了する限り、親プロセスは引き続き実行されますが、親プロセスは子プロセスのステータスを読み取らず、子プロセスは Z 状態に入ります。
3. ゾンビプロセスを作成する
30 秒間続くゾンビ プロセスを作成する例を見てみましょう。
#include <stdio.h>
#include <stdlib.h>
int main()
{
pid_t id = fork();
if(id < 0)
{
perror("fork");
return 1;
}
else if(id > 0)
{ //parent
printf("parent[%d] is sleeping...\n", getpid());
sleep(30);
}
else
{
printf("child[%d] is begin Z...\n", getpid());
sleep(5);
exit(EXIT_SUCCESS);
}
return 0;
}
別の端末でコンパイルして監視します。
テストを開始します:
結果を参照してください。
注: ptrace システム コールはプロセスの実行を追跡します。興味があれば調べてください。
4. ゾンビプロセスの害
1. プロセスの終了ステータスは、それを気にするプロセス (親プロセス) に、あなたから与えられたタスクをどのように実行したかを伝える必要があるため、維持する必要があります。しかし、 親プロセスがまったく読み取りを行わない場合、子プロセスは常に Z 状態になります?。
はい!
2. 終了ステータスの維持自体にはデータのメンテナンスが必要であり、プロセスの基本情報でもあるため、task_struct (PCB) に保存されます。つまり Z ステータスは決して終了しない、PCB は常にメンテナンスが必要?
はい!
メモリ リソースの無駄遣いが発生します?
はい! データ構造オブジェクト自体がメモリを占有するため、C で構造変数 (オブジェクト) を定義してメモリのどこかにスペースを空けることを検討してください。
4.内部残留漏れ?
はい!
5. ゾンビプロセスを回避する方法
1.wait() または waitpid() 関数を使用する: 親プロセスで wait() または waitpid() 関数を呼び出します。 and wait 子プロセスが終了し、ステータス コードを返します。これにより、子プロセスが終了した後、そのリソースが正常にリサイクルされ、ゾンビ プロセスの生成が回避されます。
2.シグナル ハンドラー プログラムを使用する: SIGCHLD シグナル ハンドラーを親プロセスに登録します。子プロセスが終了すると、子プロセスに通知されます。親プロセスはこのシグナルを送信し、親プロセスはシグナル ハンドラーで wait() または waitpid() 関数を呼び出して、子プロセスのリソースを再利用できます。
3.fork() を 2 回: 最初のフォークの子プロセスは、フォークが完了した直後に終了するため、2 番目のフォークは取得された子プロセスには父親がなくなり、祖先の init プロセスによって自動的に採用されます。init はそのリソースを解放する責任を負うため、「ゾンビ」は生成されません。
2. オーファンプロセス
1. 関連概念
質問: 親プロセスが早期に終了し、子プロセスが後で終了して Z に入った場合、どうすればよいですか?
親プロセスが最初に終了し、子プロセスは「孤立プロセス」と呼ばれます。孤立プロセスは初期プロセス 1 によって採用されます。もちろん、それはinit プロセスによってリサイクルされます。 a>
2. 孤立したプロセスを作成する
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int main()
{
pid_t id = fork();
if(id < 0)
{
perror("fork");
return 1;
}
else if(id == 0)
{//child
printf("I am child, pid : %d\n", getpid());
sleep(10);
}
else
{//parent
printf("I am parent, pid: %d\n", getpid());
sleep(3);
exit(0);
}
return 0;
}
具体的な実装は上記と同じです。
3. 孤立したプロセスの害
孤立プロセスは親プロセスのないプロセスです。孤立プロセスの重要なタスクは init プロセスにあります。init プロセスは民事局のようなもので、孤立プロセスの事後処理を担当します。孤立したプロセスが現れるたびに、カーネルは孤立したプロセスの親プロセスを init に設定し、init プロセスは終了した子プロセスを周期的に wait() します。このようにして、孤立プロセスがライフサイクルを悲惨な形で終了した場合、init プロセスが党と政府に代わってその後のすべての処理を行います。
したがって、孤立プロセスでは害はありません。
3. プロセスの優先順位
1. 関連概念
CPU リソースが割り当てられる順序は、プロセスの優先順位を表します。
優先度の高いプロセスには優先実行権限が与えられます。プロセスの優先順位の構成は、マルチタスク環境の Linux にとって非常に役立ち、システムのパフォーマンスを向上させることができます。
指定した CPU でプロセスを実行することもでき、重要でないプロセスを特定の CPU に配置することで、システム全体のパフォーマンスを大幅に向上させることができます。
2. システムプロセスの表示
Linux または UNIX システムで ps-l コマンドを使用すると、次のような出力が表示されます。
次のようないくつかの重要な情報に簡単に気づくことができます。
UID: 実行者の ID を表します
PID: このプロセスのコード名を表します
PPID: このプロセスの派生元のプロセス、つまり親プロセスのコード名を表します。
PRI: この処理を実行できる優先度を表し、値が小さいほど早く実行されます。
Nl: このプロセスの優れた価値を表します
3.PRI と NI
4.PRI と NI
プロセスのnice値はプロセスの優先度ではなく、同じ概念ではありませんが、プロセスのnice値はプロセスの優先度の変更に影響を与えることを強調しておく必要があります。
nice 値はプロセス優先度の修正データであることがわかります。
結論:Linux システムにおけるプロセスの二次共有はこれで終了です。デモなしで操作を練習できます。この記事の共有が皆様のお役に立てれば幸いです。この研究はいくつかの助けになりました。ご質問がございましたら、コメント欄にメッセージを残してください~~~