システムコールに使用されているプロセスを一覧表示するには?コマンドで検索する方法はありますかtop
?マニュアルページで適切なオプションが見つかりません。
答え1
プロセスの状態は、プロセスが実行している操作を示します。主なプロセス状態は次のとおりです。
- S:スリープ、つまりシステムコールで何かを待つのをブロックします。プロセスに何が起こるかを覚醒させることができます。
- D:使用中です。ハードウェアを待っています。中断のない省電力モードです。プロセスは覚醒できず、特定のイベントが発生するまで待つ必要があります。 (キャンセル可能な場合もありますが、必ずしもそうではありません。)
- R:実行、つまりコードを実行します。これは通常アプリケーションコードなので、ユーザーモードで実行されますが、カーネルで内部的に実行されるいくつかの計算もRでプロセス状態を維持します。
カーネルが内部的に実行する計算は、RまたはD状態にすることができます。私はこれらの計算がリソースを使用しているかどうか(たとえば、コードにロックがあるかどうか)によって異なると思います。 R-in-user-modeとR-in-kernelモードを区別する移植可能な直接的な方法はないと思いますが、おそらく/proc
Linuxのどこかに方法があるでしょう。
Linux procps の最上位バージョンにはプロセスのステータスが一覧表示されます。ステータスDのプロセスのみをリストするオプションはないようですが、キーまたはコマンドラインオプションを使用して、最後の画面更新以降にアイドル状態のままになっているすべてのプロセスを非表示にできi
ます-i
。プロセス。
PIDのみをリストしたい場合は、出力をフィルタリングできますps
。
ps -o state=,pid= | sed -n 's/^D //p'
多くのI / Oを実行しないシステムでは、ほとんどの場合、プロセスはゼロとしてリストされます。
答え2
これは100%完璧な答えではありませんが、感じを与えます。常に「R」状態のプロセスがある場合は、procfsの2つのフィールド監視を開始できます。
$ awk '{print $14, $15}' /proc/$$/stat
次の内容が表示されます。 0 3915
最初の数字は「このプロセスがユーザーモードでスケジュールされた時間(時計の目盛りで測定)」を示し、2番目の数字は「このプロセスがカーネルモードで予約された時間(時計の目盛りで測定)」を示します。 (詳細はman procを参照してください)
しかし、コアは、3915が非常に急速に増加し、ゼロがそうでない場合、プロセスはカーネルモードで実行中であることを意味することです。 3915が急速に成長するにつれて、プロセスがKehelモードで実行されているという確信は大きくなります。
一例:
$ sudo dd if=/dev/nvme0n1p2 of=/dev/null bs=30M count=1000
$ top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
16691 root 20 0 45352 32712 2112 R 50,5 0,2 0:06.00 dd
$ awk '{print $14, $15}' /proc/16691/stat
0 467
$ awk '{print $14, $15}' /proc/16691/stat
0 512
$ awk '{print $14, $15}' /proc/16691/stat
0 557
$ awk '{print $14, $15}' /proc/16691/stat
0 594
$ awk '{print $14, $15}' /proc/16691/stat
0 630
$ awk '{print $14, $15}' /proc/16691/stat
0 666
$ awk '{print $14, $15}' /proc/16691/stat
0 699
したがって、はい、プロセスはカーネルモードで実行されていると言えます。
「D」状態の場合:
「D」状態の場合(間違っている場合は訂正してください) - これはプロセスが「休止」状態にあることを意味します。これは「ノンストップスリープ」状態であり、とにかくスリープ状態です。これは、プロセスのコード(ユーザースペース)またはシステムコールを介して呼び出されたカーネルコードが、一部の必要なデータが出るまでCPUに予約されていないことを意味します。構造を使用できます。したがって、「D」状態のプロセスはレビューの対象から除外されるべきだと思います。なぜ? CPUではまったく動作しないからです。しかし、微妙な瞬間があります。プロセスは「D」状態と「R」状態の間をすばやく切り替えることができるため、プロセスは「D」状態にあると考えることができますが、時には「R」状態に切り替えることがあります。
詳しく説明します。人々は、プロセスが「D」状態にあると、いくつかのI \ Oを待っていることを意味すると頻繁に言います。しかし、実際にはそうではありません。
Cで書かれたシンプルなプログラム
$ cat 30.c
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
int main() {
pid_t pid = vfork();
if (pid == 0) {
sleep(180);
return 0;
}
printf("parent: I am exiting\n");
return(0);
}
編む。
$ gcc -o 30.exe 30.c
放射。
$ ./30.exe
vfork を使用して子プロセスを作成します。親プロセスは、子プロセスが終了するまでブロックされます。親プロセスの状態も「D」である。
$ ps aux | grep 30.exe
vasya 6495 0.0 0.0 10700 964 pts/66 D+ 03:30 0:00 ./30.exe
vasya 6496 0.0 0.0 10700 964 pts/66 S+ 03:30 0:00 ./30.exe
したがって、親プロセスはi \ o操作を実行しませんが、「D」状態を持ちます。
次へ - 「D」を持つプロセスがCPUを使用しているかどうかを見てみましょう。それでは、実際に眠りに落ちたことを確認してみましょうか?
$ while true; do cat /proc/6495/stat | awk '{print $3, $14, $15}'; done
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
D 0 0
私たちが見ることができるように。
次へ。 「D」状態のプロセスはしばしば見られますが、「top」はCPUを消費することを示します。どうやってこれができますか?クイック答え - プロセスは「D」と「R」の状態を切り替えます。それはすぐに起こることができます。 "top"はprocfsからすべての情報を読むことを覚えておいてください。デフォルトでは、「top」はすべてのデータを3秒ごとに更新するため、プロセスが「R」状態より「D」状態に頻繁に切り替えられる場合、私たちの観点からは、プロセスは常に「D」状態です。しかし、これは間違った仮定です。
次に重要なのは、プロセスの状態が瞬間的であるという属性です。つまり、プロセスが「D」状態にあると言うとき、これはそのプロセスが特定の時間にこの状態にあることを意味します。しかし、CPU消費について話すとき、これは瞬間的な時間の属性とは何の関係もありません。一定期間の平均です。写真を見てください:
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
13416 vasya 20 0 24024 5308 2132 D 62,9 0,0 0:05.02 dd
ステータス = 'D'%CPU = 62,9が表示されます。
これは現在の(現在の)ステータス= 'D'を意味します。これは、現在のプロセスがCPUサイクルを消費していないが、しばらく前にプロセスが「D」状態ではなく、CPUサイクルを消費していることを意味します。したがって、単純化のために、「top」は最後の3秒の平均を計算します。次のように見えます。
Now - 0%
1 sec ago - 62,9%
2 sec ago - 62,9%
3 sec ago - 62,9%
the average = (62,9%+62,9%+62,9%+0%)/(1+1+1) = 62,9%
これがプロセスの状態が「D」であるにもかかわらず、「トップ」が62.9%のCPU使用率を示す理由です。
「dd」が「D」と「R」の状態を切り替えていることを示すには、次のようにします。
$ while true; do cat /proc/13416/stat | awk '{print $3, $14, $15}'; done
R 0 745
R 0 745
D 0 746
D 0 746
D 0 746
D 0 746
D 0 746
D 0 746
R 0 746
R 0 746
R 0 746
R 0 747
R 0 747
R 0 747
R 0 748
D 0 748
D 0 748
D 0 748
D 0 748
R 0 748
R 0 748
R 0 749
D 0 749
R 0 749
R 0 749
D 0 750
D 0 750
D 0 750
D 0 750
D 0 750
D 0 750
R 0 750
R 0 751
R 0 751
R 0 752
R 0 752
R 0 752
D 0 752
D 0 752
D 0 752
D 0 752
D 0 752
R 0 753
R 0 753
D 0 753
D 0 753
D 0 753
D 0 753
R 0 754
R 0 754
R 0 755
R 0 755
D 0 756
D 0 756
$14 および %15 フィールドの意味: "man proc" の場合:
$ 14 =このプロセスがユーザーモードでスケジュールされた時間(クロックサイクル)(sysconf(_SC_CLK_TCK)で割った)。
$ 15 =このプロセスがカーネルモードで予約された時間(クロックサイクル)(sysconf(_SC_CLK_TCK)で割った)。
ご覧のとおり、「dd」は「R」と「D」の状態を切り替えます。平均CPU使用率が0%でない理由はここにあります。
また、プロセスが実際に「D」状態にある間は、ユーザーモードまたはカーネルモードでCPUサイクルを消費しないことがわかります。
最後のアドバイス:プロセスがあり、現在のユーザースペースまたはカーネルスペースで実行されているかどうかを知りたい場合は、-->監視を開始してください。
$ cat /proc/13416/stat | awk '{print $3, $14, $15}';
$14 が変更されるとプロセスがユーザー空間にあることを意味し、%15 が変更されるとプロセスがカーネル空間にあるという意味です。
それがあなたに役立つことを願っています
答え3
~によるとソースコード、topではこれを行うことはできません。
それにもかかわらず、topには-p
特定のPIDのみを監視するように指示するパラメータがあります。残念ながら、このパラメータも20個のパラメータに制限されており、カーネルは20個以上のプロセスを簡単に実行できます。
テストするために2行のスクリプトを作成しました。
kprocs=$(ls -l /proc/*/exe | grep -v " -> " | cut -d "/" -f 3)
top -c -p $(echo ${kprocs} | sed 's/ /,/g')
さまよう場合は、ディスクのバイナリを指さないリンクをチェックしてカーネルプロセスを検出します。