top 명령 - 프로세스의 CPU가 합산되지 않습니다.

top 명령 - 프로세스의 CPU가 합산되지 않습니다.

top명령( 6.5%us, 17.2%sy, 등...) 으로 보고된 다양한 유형의 CPU 사용량을 이해 0.0%ni하지만 각 프로세스의 총 %CPU가 어떤 값에도 추가되지 않는 이유는 무엇입니까 Cpu(s)? 예를 들어 아래 Java 프로세스는 77.5%의 CPU를 소비하고 있지만 Cpu(s)76.0%는 여전히 유휴 상태입니다. 왜 이런거야? 이것은 단일 코어 시스템에 있습니다.

top - 05:53:27 up 32 min,  2 users,  load average: 0.16, 0.29, 0.34
Tasks:  71 total,   1 running,  70 sleeping,   0 stopped,   0 zombie
Cpu(s):  6.5%us, 17.2%sy,  0.0%ni, 76.0%id,  0.0%wa,  0.0%hi,  0.3%si,  0.0%st
Mem:   1758616k total,   643432k used,  1115184k free,    12224k buffers
Swap:   917500k total,        0k used,   917500k free,   304608k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                                                      
 1307 tomcat    20   0  683m 287m 9528 S 77.5 16.8  10:54.99 java                                                                                                                                                                          
 1571 ec2-user  20   0  2592 1096  872 R  1.0  0.1   0:08.61 top                                                                                                                                                                           
    1 root      20   0  2892 1364 1168 S  0.0  0.1   0:00.28 init                                                                                                                                                                          
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd            

편집하다: 알고 보니 듀얼 코어 시스템이었습니다. 다음은 top명령이 실행되는 동안 1을 누른 후 업데이트된 출력입니다 .

top - 06:10:21 up 49 min,  2 users,  load average: 0.28, 0.37, 0.34
Tasks:  71 total,   1 running,  70 sleeping,   0 stopped,   0 zombie
Cpu0  :  9.9%us, 19.7%sy,  0.0%ni, 69.0%id,  0.0%wa,  0.0%hi,  1.4%si,  0.0%st
Cpu1  :  5.0%us, 10.0%sy,  0.0%ni, 85.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:   1758616k total,   677548k used,  1081068k free,    13296k buffers
Swap:   917500k total,        0k used,   917500k free,   305732k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                                                      
 1307 tomcat    20   0  683m 318m 9528 S 68.0 18.6  17:23.53 java                                                                                                                                                                          
    1 root      20   0  2892 1364 1168 S  0.0  0.1   0:00.28 init                                                                                                                                                                          
    2 root      20   0     0    0    0 S  0.0  0.0   0:00.00 kthreadd                                                                                                                                                                      
    3 root      20   0     0    0    0 S  0.0  0.0   0:00.91 ksoftirqd/0                                                                                                                                                                   
    4 root      RT   0     0    0    0 S  0.0  0.0   0:00.00 migration/0   

답변1

비교하고 있는 두 정보는 서로 다른 파일에서 수집되었기 때문에 일치하지 않습니다. 즉, top은 동일한 터미널에 정보를 표시하지만 동일한 소스에서 수집되지는 않습니다.

나는 단순히 위에서 strace를 실행했습니다(배치 모드에서 실행). 여기에는 시스템 전반의 CPU 정보가 표시됩니다.

16:04:04.081092 open("/proc/stat", O_RDONLY) = 6 <0.000022>
16:04:04.081154 lstat("/proc", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0 <0.000015>
16:04:04.081211 lstat("/proc/stat", {st_mode=S_IFREG|0444, st_size=0, ...}) = 0     <0.000013>
16:04:04.081267 fstat(6, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 <0.000013>
16:04:04.081334 fstat(6, {st_mode=S_IFREG|0444, st_size=0, ...}) = 0 <0.000013>
16:04:04.081385 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f699ace2000 <0.000016>
16:04:04.081440 lseek(6, 0, SEEK_SET)   = 0 <0.000013>
16:04:04.081494 read(6, "cpu  302573 6910 83103 10092403 "..., 1024) = 1024 <0.000070>
16:04:04.081656 write(1, "%Cpu(s):  2.9 us,  0.8 sy,  0.1 "..., 80) = 80 <0.000034>
16:04:04.081763 write(1, "KiB Mem:   8048484 total,  41402"..., 73) = 73 <0.000035>
16:04:04.081858 write(1, "KiB Swap:  8060924 total,       "..., 72) = 72 <0.000034>
16:04:04.081940 write(1, "\n", 1)       = 1 <0.000026>

이제 이 표시되면 /proc/stat시스템의 모든 CPU가 표시됩니다. top도 이를 알고 있습니다. /proc/stat를 열기 전에 sys 파일 시스템을 열기 때문입니다.

16:04:03.367339 open("/sys/devices/system/cpu/online", O_RDONLY|O_CLOEXEC) = 3 <0.000027>
16:04:03.367408 read(3, "0-7\n", 8192)  = 4 <0.000019>
16:04:03.367464 close(3)                = 0 <0.000015>

이제 개별 프로세스 정보를 수집할 때 해당 정보를 파일에서 가져 /proc/pid/statm옵니다 /proc/pid/stat. (pid를 실제 pid로 바꾸십시오).

보시다시피 /proc/stat시스템 전체에 대한 정보는 다음과 같습니다.모두pid에 대한 CPU 및 개별 proc 파일은 특정 pid 전용 정보입니다.

그래서 그들은 일치하지 않을 것입니다.

답변2

CPU 사용량을 측정 하는 샘플링에는 top오류가 발생할 수 있습니다.

이를 설명하는 가장 좋은 방법은 다음과 같습니다. 시간당, 정시에 정확히 한 대의 자동차를 생산하는 공장을 상상해 보십시오. 공장에서 자동차를 생산하는 속도를 샘플링하기로 결정했다고 가정해 보겠습니다. 5시 59분에 샘플링을 시작하고 7시 1분에 샘플링을 중지합니다. 두 대의 자동차가 생산되는 것을 볼 수 있습니다. 한 대는 6시에, 다른 한 대는 7시에 생산됩니다. 62분 동안 샘플링을 하셔서 2대의 자동차가 생산되었습니다. 따라서 공장이 정격 용량의 약 200%로 자동차를 생산하고 있다고 계산합니다.

또한 단일 시스템 상태에 대한 측정 세트를 제공하지 않고 각각 고유한 조건 세트에 따라 독립적인 측정 세트를 제공하므로 top값을 서로 비교할 수 없습니다.top

예를 들어 CPU별 값은 프로세스별 값과 완전히 다른 메커니즘을 사용하여 계산할 수 있습니다. CPU당 값은 기하급수적으로 감소할 수 있지만 프로세스당 값은 두 합계 간의 차이가 될 수 있습니다. 따라서 동일한 유형의 측정값을 반영할 수 있지만 완전히 다른 방법론을 사용합니다.

관련 정보