【Linux】プロセスステータス
プロセスステータスの概念
プロセスのステータスを理解する前に、実行中のプロセスは常に CPU で計算を実行しているわけではなく、オペレーティング システムの管理下にあり、他の実行中のプロセスと交代で CPU を使用することを知っておく必要があります。システムはプロセスを管理しますか? プロセスのステータスに基づいて計算のために CPU に配置されます。
ブロッキング状態
ブロッキング状態は、プロセスが特定のリソースの準備ができるのを待っていることによって引き起こされる非進行状態です。
ブロック状態は主観的にプロセスが「スタック」しているという印象を与えます。たとえば、プロセスが特定のソフトウェアをダウンロードしているときにネットワークが切断された場合、ソフトウェアのダウンロードプロセスは「スタック」し、プロセスは待機する必要があります。ネットワークなどのリソース。準備ができてから先に進むことができます。したがって、プロセスがブロックされているときは、何らかのリソースを待機している必要があります。プロセスは、特定のリソースが自分自身で使用される前に、他のユーザーによって使用されるのを待機するため、ブロッキング状態になります。
オペレーティング システムはさまざまなハードウェアを管理する必要があるため、特定の構造を使用してハードウェアを記述し、その構造を整理して管理しやすくする必要があります。これらのハードウェアを記述する際には、待機キューの記述が含まれます。このキューは、現在のハードウェア リソースを待機しているプロセスの PCB を記録します。オペレーティング システムは、次の一般原則を実装して、プロセスをブロック状態にします。
保留状態
サスペンド状態とは、プロセスが特定のリソースの準備ができるのを待っている間に、オペレーティング システムがメモリ内のプロセスのコードとデータを解放する状態です。
サスペンド状態では、プロセスの PCB はまだハードウェアの待機キューにあり、プロセスが待機しているリソースの準備ができるまでに時間がかかるとオペレーティング システムが判断すると、コードとデータが解放されます。余分なメモリ領域を確保するために、メモリ内にプロセスを追加します。これは、他のことを実行したり、メモリ使用率を向上させるために使用されます。プロセスが待機しているリソースの準備ができたら、オペレーティング システムはプロセスのコードとデータをメモリを確保してプロセスを開始します。
Linuxでのプロセスステータス
Linux システムでは、次のプロセス ステータスがカーネル ソース コードで定義されます。
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"X (dead)", /* 16 */
"Z (zombie)", /* 32 */
};
注: Linux のプロセスは、プロセスのステータスを記録するために task_struct に変数を設定します。
R状態
R 状態は実行状態です。これは、プロセスの task_struct がオペレーティング システムの実行状態待機キューにあり、オペレーティング システムによる実行状態のプロセスのコードのサイクル実行中に実行されることを意味します。
注:実行中のプロセスは、常に CPU 上で実行されるという意味ではなく、他の実行中のプロセスと同様にラウンドロビン方式で実行されます。
R ステータスを確認するには、次のコードを記述します。
#include <stdio.h>
int main()
{
while(1)
{
}
return 0;
}
Linux システムでプログラムを実行し、プロセスのステータスを表示します。
このコードの実行にはリソースが必要ないため、ブロック状態にはならず、実行されたままになります。
S状態
S 状態は割り込み可能なスリープ状態であり、Linux システムのブロッキング状態です。
S 状態を確認するには、次のコードを記述します。
#include <stdio.h>
int main()
{
while(1)
{
printf("hello world\n");
}
return 0;
}
Linux システムでプログラムを実行し、プロセスのステータスを表示します。
このコードのプログラムは無限ループ操作ですが、ループ構造内のコードは非常に高速に実行されるため、画面へのデータの出力は非常に遅く、プログラムの実行中のほとんどの時間は画面の表示を待機しています。したがって、ステータスをクエリするときは、ほとんどの場合、S ステータスがクエリされます。また、休止状態のプロセスを中断し、ctrl+z
終了プロセスに入るかを選択できます。
D状態
D 状態は中断不可能なスリープ状態であり、Linux システムのブロッキング状態です。
D 状態は、プロセスがメモリからディスクにデータを転送するときです。ディスクの圧力が高すぎるため、データ転送速度が非常に遅くなります。プロセスはデータ転送が完了するまで待機し、休止状態のままにする必要があります。オペレーティング システムが休止状態のプロセスを強制終了しないようにするために、プロセスは中断不可能なスリープ状態に設定されます。D 状態は一般的な状態ではありません。プロセスが D 状態にある場合は、通常、コンピュータのディスク圧力が高すぎることを意味します。
T 状態
T 状態は一時停止状態であり、プロセスは一時停止状態では実行を継続できません。
T ステータスを確認するには、次のコードを記述します。
#include <stdio.h>
#include <unistd.h>
int main()
{
int i = 1;
while(1)
{
printf("hello world %d\n", i);
i++;
sleep(1); //Linux系统提供的休眠函数,头文件是unistd.h
}
return 0;
}
Linux システムでプログラムを実行するには、kill -19 进程id
プロセスを一時停止し、プロセスのステータスを表示します。
次のように入力すると、プロセスを再起動できますkill -18 进程id
。
補足: Linux でのプロセス ステータスの後の + は、これがフォアグラウンド プロセスであることを意味します。
プロセスステータスに + が付いていないものはバックグラウンドプロセスです。
Linux 上でフォアグラウンドプロセスが実行されている場合は bash は無効ですが、バックグラウンドプロセスが実行されている場合は bash が使用でき、また、バックグラウンドプロセスは を使用してシャットダウンできますkill -9 进程id
。
状態
t 状態は追跡一時停止状態であり、T 状態の特殊なケースです。
t ステータスを確認するには、gdb ツールを借用し、gdb を使用してプログラムのデバッグを開始します。
Z状態
Z状態はゾンビ状態と呼ばれ、プロセスは完全に停止しているが、task_structやプロセスの一部のデータは保持されている。プロセスがゾンビ状態になる目的は、保持するデータには終了コードなどの情報が含まれており、終了コードはプロセスに問題があるかどうかを判断するためのデータであるため、プロセスの実行結果に問題があるかどうかを知ることが目的です。プロセスの実行結果。プロセスが終了すると、ゾンビ状態になり、親プロセスによるリサイクルを待ちます。
T ステータスを確認するには、次のコードを記述します。
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t id = fork();
if (id == 0)
{
//子进程
while(1)
{
printf("我是子进程,我的pid:%d,我的ppid:%d\n", getpid(), getppid());
sleep(1);
}
}
else if (id > 0)
{
while(1)
{
printf("我是父进程,我的pid:%d,我的ppid:%d\n", getpid(), getppid());
sleep(1);
}
}
return 0;
}
Linux システムでプログラムを実行するには、kill -9 进程id
子プロセスを強制終了し、プロセスのステータスを表示します。
ゾンビプロセスの弊害:プロセスのtask_structとデータがゾンビ状態で保持されるため、メモリ空間を占有し、複数の子プロセスが作成されリサイクルされないと、大量の空間が占有され、重大なメモリリークが発生します。
Xステータス
X 状態はデス ステートと呼ばれ、プロセスが完全に停止し、オペレーティング システムはプロセスの task_struct、コード、データをすぐにリサイクルして解放します。
孤立したプロセス
孤立プロセスとは、プロセスの実行中に親プロセスが停止し、親プロセスがオペレーティングシステム(プロセスNo.1)に変換された場合に、オペレーティングシステムによって管理されるプロセスです。
孤立したプロセスを確認するには、次のコードを記述します。
#include <stdio.h>
#include <unistd.h>
int main()
{
pid_t id = fork();
if (id == 0)
{
//子进程
while(1)
{
printf("我是子进程,我的pid:%d, 我的ppid:%d\n", getpid(), getppid());
sleep(1);
}
}
else if (id > 0)
{
//父进程
int cnt = 5;
while(1)
{
printf("我是父进程,我的pid:%d, 我的ppid:%d\n", getpid(), getppid());
sleep(1);
if (--cnt == 0) break;
}
}
return 0;
}
コンパイルを容易にするために、次の Makefile を作成します。
myproc:myproc.c
gcc -o $@ $^
.PHONY:clean
clean:
rm -f myproc
コードとメイクファイルを準備した後、プログラムをコンパイルして実行し、while :; do ps axj | head -1 && ps axj | grep myproc | grep -v grep; sleep 1; done
コマンドを使用してプロセスのステータスを毎秒クエリします。
プロセス myproc の親プロセスの親プロセスは bash です。停止してゾンビ状態になった後、bash は親プロセスとしてリサイクル操作を実行するため、ゾンビ状態は表示されません。プロセス myproc の子プロセスはまだ進行中ですが、元の親プロセスが停止した場合、それをリサイクルするには新しい親プロセスが必要です。そうしないと、停止後にゾンビ状態をリサイクルできません。
孤立プロセスになった後はバックグラウンド プロセスになり、killall 进程名
同じプロセス名を持つすべてのプロセスを強制終了する命令を使用することを選択できます。