Come calcolare l’utilizzo della CPU di un processo da PID in Linux da C?

Voglio programmaticamente [in C] calcolare l’% di utilizzo della CPU per un dato ID di processo in Linux.

Come possiamo ottenere la percentuale di utilizzo della CPU in tempo reale per un dato processo?

Per chiarire ulteriormente:

  • Dovrei essere in grado di determinare l’utilizzo della CPU per il processid o il processo fornito.
  • Il processo non deve essere il processo secondario.
  • Voglio la soluzione in linguaggio ‘C’.

È necessario analizzare i dati da /proc//stat . Questi sono i primi campi (da Documentation/filesystems/proc.txt nella sorgente del tuo kernel):

 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 

Probabilmente sei in utime e / o stime . Dovrai anche leggere la riga della cpu da /proc/stat , che assomiglia a:

 cpu 192369 7119 480152 122044337 14142 9937 26747 0 0 

Questo ti dice il tempo di CPU cumulativo che è stato usato in varie categorie, in unità di jiffies. È necessario prendere la sum dei valori su questa riga per ottenere una misura time_total .

Leggi sia utime che stime per il processo che ti interessa e leggi time_total da /proc/stat . Poi dormi per un secondo o due, e rileggili tutti di nuovo. Ora puoi calcolare l’utilizzo della CPU del processo nel tempo di campionamento, con:

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

Ha senso?

getrusage () può aiutarti a determinare l’utilizzo del processo corrente o suo figlio

Aggiornamento: non riesco a ricordare un’API. Ma tutti i dettagli saranno in / proc / PID / stat, quindi se potessimo analizzarlo, possiamo ottenere la percentuale.

EDIT: Poiché la CPU% non è semplice da calcolare, qui puoi usare il tipo di campionamento. Leggi ctime e utime per un PID in un punto nel tempo e leggi nuovamente gli stessi valori dopo 1 secondo. Trova la differenza e dividila per cento. Otterrai l’utilizzo per quel processo per oltre un secondo.

(potrebbe diventare più complesso se ci sono molti processori)

facile passo per passo per noccioline come me 🙂

leggi la prima riga di / proc / stat per ottenere total_cpu_usage1

 sscanf(line,"%*s %llu %llu %llu %llu",&user,&nice,&system,&idle); total_cpu_usage1 = user + nice + system + idle; 

leggi / proc / pid / stat dove pid è il pid del processo che vuoi conoscere l’utilizzo della cpu, come questo:

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

ora sum usertime e ora di sistema e ottieni proc_times1

ora aspetta 1 o più secondi

fallo di nuovo e ottieni total_cpu_usage2 e proc_times2

la formula è:

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

puoi ottenere il numero di cpu da / proc / cpuinfo

Ho scritto due piccole funzioni C basate su cafs risposta per calcolare l’utilizzo della CPU utente + kernel di un processo: https://github.com/fho/code_snippets/blob/master/c/getusage.c

Puoi leggere la manpage per proc per maggiori dettagli, ma in sintesi puoi leggere / proc / [numero] / stat per ottenere le informazioni su un processo. Questo è anche usato dal comando ‘ps’.

Tutti i campi e i loro specificatori del formato scanf sono documentati nella manpag proc .

Ecco alcune delle informazioni dalla pagina man copiata (è piuttosto lunga):

  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. 

Dai un’occhiata al comando “pidstat”, sembra esattamente quello che ti serve.

Questa è la mia soluzione …

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

Quando si desidera monitorare il processo specificato, in genere viene eseguito tramite script. Ecco perl esempio. Questo mette le percentuali allo stesso modo di quelle migliori, scalandole a una CPU. Quindi quando alcuni processi sono attivi con 2 thread, l’utilizzo della CPU può essere superiore al 100%. Guarda in particolare come vengono contati i core della CPU: D quindi fammi mostrare il mio esempio:

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

Spero che ti possa aiutare in qualsiasi monitoraggio. Ovviamente dovresti usare scanf o altre funzioni C per convertire qualsiasi regexipe di perl che ho usato nel sorgente C. Ovviamente 1 secondo per dormire non è obbligatorio. puoi usare in qualsiasi momento l’effetto è, si otterrà il carico di valutazione su un periodo di tempo specificato. Quando lo userai per il monitoraggio, ovviamente gli ultimi valori che dovresti mettere all’esterno. È necessario, perché il monitoraggio di solito chiama gli script periodicamente, e lo script dovrebbe terminare il suo lavoro al più presto.

Installa il pacchetto psacct o acct . Quindi utilizzare il comando sa per visualizzare il tempo della CPU utilizzato per vari comandi. pagina di uomo

Un bel howto dal sito di nixCraft.

Penso che valga la pena guardare il codice sorgente del comando “time” di GNU. tempo Emette il tempo di CPU utente / sistema insieme al tempo reale trascorso. Chiama la chiamata di sistema wait3 / wait4 (se disponibile) e in caso contrario chiama la chiamata di sistema. wait * la chiamata di sistema restituisce una variabile di struttura “rusage” e le volte che la chiamata di sistema restituisce “tms”. Inoltre, è ansible dare un’occhiata alla chiamata di sistema getrusage che restituisce anche informazioni di temporizzazione molto interessanti. tempo

Invece di analizzare questo da proc, si possono usare funzioni come getrusage () o clock_gettime () e calcolare l’utilizzo della cpu come un rapporto o tempo di wallclock e il tempo del processo / thread usato sulla CPU.