Hoe bereken je het CPU-gebruik van een proces door PID in Linux vanuit C?

Ik wil programmatisch [in C] het CPU-gebruikspercentage berekenen voor een gegeven proces-ID in Linux.

Hoe kunnen we het realtime CPU-gebruikspercentage voor een bepaald proces krijgen?

Om het verder duidelijk te maken:

  • Ik zou het CPU-gebruik moeten kunnen bepalen voor het opgegeven proces-ID of proces.
  • Het proces hoeft niet het onderliggende proces te zijn.
  • Ik wil de oplossing in ‘C’-taal.

Antwoord 1, autoriteit 100%

Je moet de gegevens uit /proc/<PID>/statontleden. Dit zijn de eerste paar velden (van Documentation/filesystems/proc.txtin je kernelbroncode):

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

Je bent waarschijnlijk op zoek naar utimeen/of stime. U moet ook de regel cpuuit /proc/statlezen, die er als volgt uitziet:

cpu  192369 7119 480152 122044337 14142 9937 26747 0 0

Dit vertelt je de cumulatieve CPU-tijd die in verschillende categorieën is gebruikt, in eenheden van jiffies. U moet de som van de waarden op deze regel nemen om een ​​time_total-meting te krijgen.

Lees zowel utimeals stimevoor het proces waarin je geïnteresseerd bent, en lees time_totalvan /proc/stat. Slaap dan een seconde of zo en lees ze allemaal nog een keer. U kunt nu het CPU-gebruik van het proces over de bemonsteringstijd berekenen met:

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);

Begrijpelijk?


Antwoord 2, autoriteit 7%

getrusage()kan u helpen bij het bepalen van het gebruik van proces of zijn kind

Bijwerken:
Ik kan me geen API herinneren. Maar alle details staan ​​in /proc/PID/stat, dus als we het zouden kunnen ontleden, kunnen we het percentage krijgen.

BEWERKEN:
Aangezien CPU% niet eenvoudig te berekenen is, zou je hier steekproeven kunnen gebruiken. Lees ctime en utime af voor een PID op een bepaald tijdstip en lees dezelfde waarden na 1 sec opnieuw. Zoek het verschil en deel het door honderd. U krijgt het gebruik voor dat proces voor de afgelopen een seconde.

(kan ingewikkelder worden als er veel processors zijn)


Antwoord 3, autoriteit 4%

Eenvoudige stap voor stap voor beginners zoals ik:

  1. Lees de eerste regel van /proc/statom total_cpu_usage1te krijgen.
   sscanf(line,"%*s %llu %llu %llu %llu",&user,&nice,&system,&idle);
    total_cpu_usage1 = user + nice + system + idle;
  1. Lees /proc/pid/statwaarbij pidde PID is van het proces waarvan je het CPU-gebruik wilt weten, als volgt:
   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. Stel nu usertimeen systemtimebij elkaar op en krijg proc_times1
  2. Wacht nu 1 seconde of langer
  3. Doe het nog een keer en krijg total_cpu_usage2en proc_times2

De formule is:

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

Je kunt het aantal CPU’s opvragen via /proc/cpuinfo.


Antwoord 4, autoriteit 3%

Ik heb twee kleine C-functies geschreven op basis van het antwoord van cafs om het gebruikers- en kernel-cpu-gebruik van een proces te berekenen:
https://github.com/fho/code_snippets/blob/master/c /getusage.c


Antwoord 5, autoriteit 2%

Je kunt de manpage voor proclezen voor meer details, maar samenvattend kun je kan /proc/[nummer]/stat lezen om de informatie over een proces te krijgen. Dit wordt ook gebruikt door het ‘ps’-commando.

Alle velden en hun scanf-indelingsspecificaties zijn gedocumenteerd in de proc manpage .

Hier zijn enkele gegevens van de manpagegekopieerd (het is vrij lang ):

         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.

Antwoord 6

Kijk eens naar het “pidstat”-commando, het klinkt als precies wat je nodig hebt.


Antwoord 7

Dit is mijn oplossing…

/*
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

Antwoord 8

Wanneer u een monitor opgegeven proces wilt, wordt het meestal uitgevoerd door scripting. Hier is Perl-voorbeeld. Dit zet percents op dezelfde manier als top, scharnierend op één CPU. Wanneer een proces actief is met werken met 2 draden, kan CPU-gebruik meer dan 100% zijn. Kijk speciaal hoe CPU-kernen worden geteld: D
Laat me dan mijn voorbeeld laten zien:

#!/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;
}

Ik hoop dat het u zal helpen bij elke monitoring. Natuurlijk moet u scanf- of andere C-functies gebruiken voor het converteren van PERL-regexpes die ik heb gewend aan C-bron.
Natuurlijk is 1 seconde voor het slapen niet verplicht. U kunt op elk gewenst moment gebruiken. Effect is, u krijgt Averrage Load op specificeerde tijdsperiode. Wanneer u het voor monitoring zult gebruiken, moet u natuurlijk de laatste waarden buiten zetten. Het is nodig, omdat monitoring gewoonlijk geen scripts oproepen, en script moet zijn werk zo snel mogelijk afmaken.


Antwoord 9

Installeer psacctof acctPAKKET. Gebruik vervolgens de opdracht saom de CPU-tijd weer te geven die wordt gebruikt voor verschillende opdrachten. sa man pagina

een leuke HOWTO van de Nixcraft-site.


Antwoord 10

Ik denk dat het de moeite waard is om naar GNU “Time” -broncode te kijken. tijd
Het geeft de gebruiker / systeem CPU-tijd af met echte verstreken tijd. Het belt Wait3 / Wait4 System Call (indien beschikbaar) en anders roept het tijden systeemgesprek. WACHT * Systeemoproep Retourneert een “Rusage” Struct-variabele en times-systeemoproep retourneert “TMS”. Ook kunt u een kijkje nemen naar GetRusage System-oproep die ook zeer interessante timing-informatie retourneert. tijd


Antwoord 11

In plaats van dit te parseren van ProC, kan men functies zoals getruSage () of Clock_getTime () gebruiken en het CPU-gebruik berekenen als een verhouding of de tijd en de tijd die het proces / draad op de CPU wordt gebruikt.


Antwoord 12

Gebruik Strace gevonden Het CPU-gebruik moet worden berekend met een tijdsperiode:

# 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
.
.
.

Other episodes