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>/stat
ontleden. Dit zijn de eerste paar velden (van Documentation/filesystems/proc.txt
in 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 utime
en/of stime
. U moet ook de regel cpu
uit /proc/stat
lezen, 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 utime
als stime
voor het proces waarin je geïnteresseerd bent, en lees time_total
van /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:
- Lees de eerste regel van
/proc/stat
omtotal_cpu_usage1
te krijgen.
sscanf(line,"%*s %llu %llu %llu %llu",&user,&nice,&system,&idle);
total_cpu_usage1 = user + nice + system + idle;
- Lees
/proc/pid/stat
waarbijpid
de 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
....)
- Stel nu
usertime
ensystemtime
bij elkaar op en krijgproc_times1
- Wacht nu 1 seconde of langer
- Doe het nog een keer en krijg
total_cpu_usage2
enproc_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 psacct
of acct
PAKKET. Gebruik vervolgens de opdracht sa
om 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
.
.
.