programing

Linux에서 C에서 프로세스의 CPU 사용량을 PID별로 계산하는 방법은 무엇입니까?

goodcopy 2022. 8. 1. 21:36
반응형

Linux에서 C에서 프로세스의 CPU 사용량을 PID별로 계산하는 방법은 무엇입니까?

Linux에서 지정된 프로세스 ID에 대한 CPU 사용률(%)을 프로그래밍 방식으로 계산하고 싶다.

특정 프로세스의 실시간 CPU 사용률(%)을 얻으려면 어떻게 해야 합니까?

좀 더 명확히 하기 위해:

  • 제공된 프로세스 ID 또는 프로세스의 CPU 사용량을 확인할 수 있어야 합니다.
  • 프로세스는 하위 프로세스일 필요는 없습니다.
  • 나는 'C' 언어로 된 해결책을 원한다.

./proc/<PID>/stat 몇 from 처음 、 from . . 。Documentation/filesystems/proc.txt"CHANGE: "CHANGE MANGHANGE:

Table 1-3: Contents of the stat files (as of 2.6.22-rc3)
..............................................................................
 Field          Content
  pid           process id
  tcomm         filename of the executable
  state         state (R is running, S is sleeping, D is sleeping in an
                uninterruptible wait, Z is zombie, T is traced or stopped)
  ppid          process id of the parent process
  pgrp          pgrp of the process
  sid           session id
  tty_nr        tty the process uses
  tty_pgrp      pgrp of the tty
  flags         task flags
  min_flt       number of minor faults
  cmin_flt      number of minor faults with child's
  maj_flt       number of major faults
  cmaj_flt      number of major faults with child's
  utime         user mode jiffies
  stime         kernel mode jiffies
  cutime        user mode jiffies with child's
  cstime        kernel mode jiffies with child's

은 아마 신신아를 쫓고 있을 utime "/"/"stime 이 때 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이, 이,cpu from from from 의 행/proc/stat뭇매를 맞다

cpu  192369 7119 480152 122044337 14142 9937 26747 0 0

이것은 다양한 카테고리에서 사용된 누적 CPU 시간을 jiffies 단위로 나타냅니다. 이 행이 .time_total하다.

다 읽다utime그리고 그리고.stime그 절차를 위해 당신을, 그리고관심 있는대한 설명입니다 프로세스에를 읽관심이 있습니다.time_total부터에서/proc/stat. 그런 다음에 일초, 다시 모든 읽는 거 보다 잠 자다.다시 읽어보세요 자고그럼 잠깐.이제,과:샘플링은 시간에 걸쳐 과정의 CPU사용량 계산할 수 있다.이제 샘플링 시간 동안프로세스의 CPU사용량을다음과 같이 계산할수 있습니다.

user_util = 100 * (utime_after - utime_before) / (time_total_after - time_total_before);
sys_util = 100 * (stime_after - stime_before) / (time_total_after - time_total_before);

이해했어?

저 같은 초보자도 쉽게 밟을 수 있는 단계입니다.

  1. 의첫 줄을 읽다의 첫번째 줄을 읽으세요/proc/stat갖기 위해를 얻기 위해total_cpu_usage1..
    sscanf(line,"%*s %llu %llu %llu %llu",&user,&nice,&system,&idle);
    total_cpu_usage1 = user + nice + system + idle;
  1. 읽어주세요를 읽어라/proc/pid/stat어디 어디에pid그 PID당신은 CPU사용량을 알고 싶고, 이:ACPU사용률을확인하는프로세스의 PID입니다고 싶다 그 과정의.다음은 예를 제시하겠습니다.
    sscanf(line,
    "%*d %*s %*c %*d" //pid,command,state,ppid

    "%*d %*d %*d %*d %*u %*lu %*lu %*lu %*lu"

    "%lu %lu" //usertime,systemtime

    "%*ld %*ld %*ld %*ld %*ld %*ld %*llu"

    "%*lu", //virtual memory size in bytes
    ....)
  1. 이제 자, 합계 요약usertime그리고 그리고.systemtimeproc_times1
  2. 이제 1초 이상 기다립니다.
  3. 번 더 얻을 수 있습니다.total_cpu_usage2 ★★★★★★★★★★★★★★★★★」proc_times2

공식은 다음과 같습니다.

(number of processors) * (proc_times2 - proc_times1) * 100 / (float) (total_cpu_usage2 - total_cpu_usage1)

은 CPU에서 수 ./proc/cpuinfo.

자세한 내용은 proc의 manpage를 참조할 수 있지만 요약하면 /proc/[number]/stat을 읽고 프로세스에 대한 정보를 얻을 수 있습니다.이 명령어는 'ps' 명령에서도 사용됩니다.

모든 필드와 해당 scanf 형식 지정자는 proc manpage에 기재되어 있습니다.

복사된 manpage의 정보를 다음에 나타냅니다(매우 깁니다).

          pid %d The process ID.

          comm %s
                 The  filename of the executable, in parentheses.  This is
                 visible whether or not the executable is swapped out.

          state %c
                 One character from the string "RSDZTW" where  R  is  runâ
                 ning,  S is sleeping in an interruptible wait, D is waitâ
                 ing in uninterruptible disk sleep,  Z  is  zombie,  T  is
                 traced or stopped (on a signal), and W is paging.

          ppid %d
                 The PID of the parent.

          pgrp %d
                 The process group ID of the process.

          session %d
                 The session ID of the process.

          tty_nr %d
                 The tty the process uses.

          tpgid %d
                 The  process group ID of the process which currently owns
                 the tty that the process is connected to.

이게 내 해결책이야

/*
this program is looking for CPU,Memory,Procs also u can look glibtop header there was a lot of usefull function have fun..
systeminfo.c
*/
#include <stdio.h>
#include <glibtop.h>
#include <glibtop/cpu.h>
#include <glibtop/mem.h>
#include <glibtop/proclist.h>



int main(){

glibtop_init();

glibtop_cpu cpu;
glibtop_mem memory;
glibtop_proclist proclist;

glibtop_get_cpu (&cpu);
glibtop_get_mem(&memory);


printf("CPU TYPE INFORMATIONS \n\n"
"Cpu Total : %ld \n"
"Cpu User : %ld \n"
"Cpu Nice : %ld \n"
"Cpu Sys : %ld \n"
"Cpu Idle : %ld \n"
"Cpu Frequences : %ld \n",
(unsigned long)cpu.total,
(unsigned long)cpu.user,
(unsigned long)cpu.nice,
(unsigned long)cpu.sys,
(unsigned long)cpu.idle,
(unsigned long)cpu.frequency);

printf("\nMEMORY USING\n\n"
"Memory Total : %ld MB\n"
"Memory Used : %ld MB\n"
"Memory Free : %ld MB\n"
"Memory Buffered : %ld MB\n"
"Memory Cached : %ld MB\n"
"Memory user : %ld MB\n"
"Memory Locked : %ld MB\n",
(unsigned long)memory.total/(1024*1024),
(unsigned long)memory.used/(1024*1024),
(unsigned long)memory.free/(1024*1024),
(unsigned long)memory.shared/(1024*1024),
(unsigned long)memory.buffer/(1024*1024),
(unsigned long)memory.cached/(1024*1024),
(unsigned long)memory.user/(1024*1024),
(unsigned long)memory.locked/(1024*1024));

int which,arg;
glibtop_get_proclist(&proclist,which,arg);
printf("%ld\n%ld\n%ld\n",
(unsigned long)proclist.number,
(unsigned long)proclist.total,
(unsigned long)proclist.size);
return 0;
}

makefile is
CC=gcc
CFLAGS=-Wall -g
CLIBS=-lgtop-2.0 -lgtop_sysdeps-2.0 -lgtop_common-2.0

cpuinfo:cpu.c
$(CC) $(CFLAGS) systeminfo.c -o systeminfo $(CLIBS)
clean:
rm -f systeminfo

프로세스의 user+module CPU 사용률을 계산하기 위해 cafs 응답에 기초한2개의 작은 C 함수를 작성했습니다.https://github.com/fho/code_snippets/blob/master/c/getusage.c

getrusage()는 현재 프로세스 또는 그 하위 프로세스의 사용 방법을 결정하는 데 도움이 됩니다.

업데이트: API가 기억나지 않습니다.그러나 모든 세부 정보는 /proc/PID/stat에 있으므로 해석할 수 있으면 퍼센티지를 얻을 수 있습니다.

편집: CPU %는 직접 계산되지 않으므로 여기서 샘플링을 사용할 수 있습니다.특정 시점에서 PID의 ctime과 utime을 읽고 1초 후에 동일한 값을 다시 읽습니다.차이를 찾아서 100으로 나누세요.그 프로세스의 이용률은 과거 1초입니다.

(프로세서가 많으면 복잡해질 수 있습니다)

"pidstat" 명령어를 참조하십시오.이 명령어는 필요한 명령어와 정확히 일치합니다.

지정된 프로세스를 감시하는 경우는, 통상은 스크립트에 의해서 실행됩니다.perl의 예를 다음에 나타냅니다.이것에 의해, 1개의 CPU에 대해서, 톱과 같이 퍼센트가 할당됩니다.2개의 스레드로 작업하는 프로세스가 액티브한 경우 CPU 사용률이 100%를 초과할 수 있습니다.특히 cpu core가 어떻게 카운트되는지를 살펴본 후 예를 제시하겠습니다.

#!/usr/bin/perl

my $pid=1234; #insert here monitored process PID

#returns current process time counters or single undef if unavailable
#returns:  1. process counter  , 2. system counter , 3. total system cpu cores
sub GetCurrentLoads {
    my $pid=shift;
    my $fh;
    my $line;
    open $fh,'<',"/proc/$pid/stat" or return undef;
    $line=<$fh>;
    close $fh;
    return undef unless $line=~/^\d+ \([^)]+\) \S \d+ \d+ \d+ \d+ -?\d+ \d+ \d+ \d+ \d+ \d+ (\d+) (\d+)/;
    my $TimeApp=$1+$2;
    my $TimeSystem=0;
    my $CpuCount=0;
    open $fh,'<',"/proc/stat" or return undef;
    while (defined($line=<$fh>)) {
        if ($line=~/^cpu\s/) {
            foreach my $nr ($line=~/\d+/g) { $TimeSystem+=$nr; };
            next;
        };
        $CpuCount++ if $line=~/^cpu\d/;
    }
    close $fh;
    return undef if $TimeSystem==0;
    return $TimeApp,$TimeSystem,$CpuCount;
}

my ($currApp,$currSys,$lastApp,$lastSys,$cores);
while () {
    ($currApp,$currSys,$cores)=GetCurrentLoads($pid);
    printf "Load is: %5.1f\%\n",($currApp-$lastApp)/($currSys-$lastSys)*$cores*100 if defined $currApp and defined $lastApp and defined $currSys and defined $lastSys;
    ($lastApp,$lastSys)=($currApp,$currSys);
    sleep 1;
}

모니터링에 도움이 되었으면 합니다.물론 scanf 또는 다른 C 함수를 사용하여 C 소스로 사용한 perl regex 유형을 변환해야 합니다.물론 수면 시간은 1초가 의무는 아닙니다.언제든지 이용하실 수 있습니다.효과는 지정된 기간에 평균 부하가 발생한다는 것입니다.모니터링에 사용할 때는 물론 마지막 값을 외부에 입력해야 합니다.모니터링은 보통 스크립트를 정기적으로 호출하고 스크립트는 작업을 최대한 빨리 완료해야 하기 때문에 필요합니다.

설치하다psacct또는acct패키지.그 후 를 사용합니다.sa다양한 명령에 사용되는 CPU 시간을 표시하는 명령어. sa man 페이지

nixCraft 사이트의 멋진 사용법.

GNU의 "time" 명령어 소스 코드를 살펴볼 가치가 있다고 생각합니다.time 사용자/시스템 CPU 시간과 실제 경과 시간을 출력합니다.wait3/wait4 시스템콜(사용 가능한 경우)을 호출합니다.그 이외의 콜은 시스템콜을 호출합니다.wait* 시스템콜은 "rusage" 구조변수를 반환하고 시스템콜은 "tms"를 반환합니다.또한 매우 흥미로운 타이밍 정보를 반환하는 getrusage 시스템 호출도 볼 수 있습니다.시간

이를 proc에서 해석하는 대신 getrusage() 또는 clock_gettime() 등의 함수를 사용하여 CPU에서 사용되는 프로세스/스레드의 비율 또는 월클럭 시간 및 시간을 계산할 수 있습니다.

strace를 사용하여 CPU 사용량을 일정 기간까지 계산해야 합니다.

# top -b -n 1 -p 3889
top - 16:46:37 up  1:04,  3 users,  load average: 0.00, 0.01, 0.02
Tasks:   1 total,   0 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
KiB Mem :  5594496 total,  5158284 free,   232132 used,   204080 buff/cache
KiB Swap:  3309564 total,  3309564 free,        0 used.  5113756 avail Mem 

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 3889 root      20   0  162016   2220   1544 S   0.0  0.0   0:05.77 top
# strace top -b -n 1 -p 3889
.
.
.
stat("/proc/3889", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/3889/stat", O_RDONLY)       = 7
read(7, "3889 (top) S 3854 3889 3854 3481"..., 1024) = 342
.
.
.

nanosleep({0, 150000000}, NULL)         = 0
.
.
.
stat("/proc/3889", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/3889/stat", O_RDONLY)       = 7
read(7, "3889 (top) S 3854 3889 3854 3481"..., 1024) = 342
.
.
.

언급URL : https://stackoverflow.com/questions/1420426/how-to-calculate-the-cpu-usage-of-a-process-by-pid-in-linux-from-c

반응형