Как вычислить использование процессора процессом PID в Linux с C?
Я хочу программно [в C] рассчитать загрузку процессора% для данного идентификатора процесса в Linux.
Как мы можем получить использование CPU в реальном времени% для данного процесса?
Чтобы сделать это более ясным:
- Я должен уметь определять использование ЦП для предоставленного processid или процесса.
- Процесс не должен быть дочерним процессом.
- Я хочу решение на языке C.
Ответы
Ответ 1
Вам нужно проанализировать данные из /proc/<PID>/stat
. Это первые несколько полей (от Documentation/filesystems/proc.txt
в вашем исходном коде ядра):
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
от /proc/stat
, которая выглядит так:
cpu 192369 7119 480152 122044337 14142 9937 26747 0 0
Это говорит о кумулятивном времени процессора, которое использовалось в разных категориях, в единицах jiffies. Вам нужно взять сумму значений в этой строке, чтобы получить меру time_total
.
Прочитайте как utime
, так и stime
для интересующего вас процесса и прочитайте time_total
из /proc/stat
. Затем спите секунду или около того, и прочитайте их все снова. Теперь вы можете рассчитать использование процессора процессом по времени выборки, используя:
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);
Имеют смысл?
Ответ 2
getrusage() может помочь вам в определении использования текущего процесса или его дочернего
Update:
Я не помню API. Но все детали будут в /proc/ PID/stat, поэтому, если мы сможем разобрать его, мы можем получить процент.
EDIT:
Поскольку CPU% не имеет прямого вычисления, вы можете использовать здесь пробоотборный материал. Прочтите ctime и utime для PID в определенный момент времени и снова прочитайте те же значения через 1 секунду. Найдите разницу и разделите на сотню. Вы получите утилиту для этого процесса за последнюю секунду.
(может быть сложнее, если есть много процессоров)
Ответ 3
простой шаг для создания нулей вроде меня:)
прочитайте первую строку /proc/stat, чтобы получить total_cpu_usage1
sscanf(line,"%*s %llu %llu %llu %llu",&user,&nice,&system,&idle);
total_cpu_usage1 = user + nice + system + idle;
read/proc/pid/stat, где pid - это 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
....)
теперь суммируйте usertime и системное время и получите proc_times1
теперь подождите 1 секунду или более
сделайте это снова и получите total_cpu_usage2 и proc_times2
формула:
(number of processors) * (proc_times2 - proc_times1) * 100 / (float) (total_cpu_usage2 - total_cpu_usage1)
вы можете получить число cpus из/proc/cpuinfo
Ответ 4
Я написал две маленькие функции C, основанные на ответах в cafs, чтобы вычислить использование пользователем + ядро cpu процесса:
https://github.com/fho/code_snippets/blob/master/c/getusage.c
Ответ 5
Вы можете прочитать manpage для proc для более подробной информации, но в итоге вы можете прочитать /proc/ [number]/stat, чтобы получить информацию о процессе. Это также используется командой "ps".
Все поля и их спецификаторы формата scanf документируются в proc manpag e.
Ниже приведена некоторая информация из 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.
Ответ 6
Это мое решение...
/*
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
Ответ 7
Взгляните на команду "pidstat", звучит точно так, как вам нужно.
Ответ 8
Если вы хотите контролировать указанный процесс, обычно это делается с помощью сценариев. Вот пример perl. Это ставит проценты так же, как и верхние, а также сбрасывает их на один процессор. Затем, когда какой-либо процесс активен, работая с 2 потоками, использование процессора может быть более 100%. Специально посмотрите, как подсчитываются ядра процессора: D
затем позвольте мне показать мой пример:
#!/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 для преобразования любых perl regexpes, которые я использовал для источника C.
Конечно, 1 секунда для сна не является обязательной. вы можете использовать любое время. эффект, вы получите усредненную нагрузку на определенный период времени. Когда вы будете использовать его для мониторинга, конечно, последние значения вы должны выставить снаружи. Это необходимо, потому что мониторинг обычно вызывает сценарии периодически, а script должен завершить свою работу как можно скорее.
Ответ 9
как насчет вывода catch (grep-ing) верхнего уровня.
Ответ 10
Установите пакет psacct
или acct
. Затем используйте команду sa
для отображения времени процессора, используемого для различных команд. sa man page
Хороший howto с сайта nixCraft.
Ответ 11
Я думаю, что стоит посмотреть на исходный код команды GNU "time". time
Он выводит время пользовательского/системного процессора вместе с реальным истекшим временем. Он вызывает системный вызов wait3/wait4 (если он доступен), и в противном случае он вызывает временный системный вызов. wait * системный вызов возвращает структурную переменную "rusage", а время системного вызова возвращает "tms". Кроме того, вы можете взглянуть на системный вызов getrusage, который также возвращает очень интересную информацию о времени. время
Ответ 12
Вместо того, чтобы анализировать это из proc, можно использовать такие функции, как getrusage() или clock_gettime(), и вычислить использование процессора в качестве отношения или времени разгона и времени процесса/потока, используемого на процессоре.