현재 커널 모드에서 실행 중인 모든 프로세스를 얻는 방법은 무엇입니까?

현재 커널 모드에서 실행 중인 모든 프로세스를 얻는 방법은 무엇입니까?

시스템 호출에 사용 중인 프로세스를 나열하는 방법은 무엇입니까? 명령어로 찾는 방법이 있나요 top? 매뉴얼 페이지에서 적절한 옵션을 찾을 수 없습니다.

답변1

프로세스의 상태는 프로세스가 수행 중인 작업을 나타냅니다. 주요 프로세스 상태는 다음과 같습니다.

  • S: Sleep, 즉 시스템 호출에서 무언가를 기다리는 것을 차단합니다. 프로세스에 할 일이 있으면 깨어날 수 있습니다.
  • D: 사용 중입니다. 하드웨어를 기다리는 중입니다. 중단 없는 절전 모드입니다. 프로세스는 깨어날 수 없으며 특정 이벤트가 발생할 때까지 기다려야 합니다. (취소가 가능한 경우도 있으나 항상 그렇지는 않습니다.)
  • R: 실행, 즉 코드를 실행합니다. 이는 일반적으로 애플리케이션 코드이므로 사용자 모드에서 실행되지만 커널에서 내부적으로 수행되는 일부 계산도 R에서 프로세스 상태를 유지합니다.

커널이 내부적으로 수행하는 계산은 R 또는 D 상태일 수 있습니다. 나는 이러한 계산이 리소스를 사용하는지 여부(예: 코드에 잠금이 있는지 여부)에 따라 다르다고 생각합니다. R-in-user-mode와 R-in-kernel 모드를 구별하는 이식 가능한 직접적인 방법은 없다고 생각하지만 아마도 /procLinux 어딘가에 방법이 있을 것입니다.

Linux procps의 최상위 버전에는 프로세스 상태가 나열됩니다. 상태 D의 프로세스만 나열하는 옵션은 없는 것 같지만 키나 명령줄 옵션을 사용하여 마지막 화면 업데이트 이후 유휴 상태로 남아 있는 모든 프로세스를 숨길 수 i있습니다 -i. 프로세스.

PID만 나열하려는 경우 출력을 필터링할 수 있습니다 ps.

ps -o state=,pid= | sed -n 's/^D //p'

I/O를 많이 수행하지 않는 시스템에서는 대부분의 경우 프로세스가 0개로 나열됩니다.

답변2

이것은 100% 완벽한 답변은 아니지만 느낌을 줍니다. 항상 "R" 상태인 프로세스가 있는 경우 procfs의 두 필드 모니터링을 시작할 수 있습니다.

$ awk '{print $14, $15}' /proc/$$/stat 

다음과 같은 내용이 표시됩니다: 0 3915

첫 번째 숫자는 "이 프로세스가 사용자 모드에서 예약된 시간(시계 틱으로 측정)"을 나타내고 두 번째 숫자는 "이 프로세스가 커널 모드에서 예약된 시간(시계 틱으로 측정)"을 나타냅니다. (자세한 내용은 man proc을 참조하세요)

그러나 핵심은 3915가 매우 빠르게 증가하고 0이 그렇지 않은 경우 프로세스가 이제 커널 모드에서 실행 중임을 의미한다는 것입니다. 3915가 더 빨리 성장할수록 프로세스가 커헬 모드에서 실행되고 있다는 확신이 더 커집니다.

한 가지 예:

$ 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"임에도 불구하고 "top"이 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개 이상의 프로세스를 쉽게 실행할 수 있습니다.

테스트하기 위해 두 줄 스크립트를 만들었습니다.

kprocs=$(ls -l /proc/*/exe | grep -v " -> " | cut -d "/" -f 3)
top -c -p $(echo ${kprocs} | sed 's/ /,/g')

방황하는 경우 디스크의 바이너리를 가리키지 않는 링크를 확인하여 커널 프로세스를 감지합니다.

관련 정보