Linuxで特定のプロセスIDのCPU使用率を[Cで]プログラムで計算したい。
特定のプロセスのリアルタイムの CPU 使用率を取得するにはどうすればよいですか?
さらに明確にするために:
- 提供されたプロセス ID またはプロセスの CPU 使用率を判断できるはずです。
- プロセスは子プロセスである必要はありません。
- 「C」言語でのソリューションが必要です。
からのデータを解析する必要があります/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
これは、さまざまなカテゴリで使用された累積CPU時間をjiffies単位で示します。測定値を取得するには、この行の値の合計をとる必要がありますtime_total
。
とあなたが興味を持っているプロセスの両方utime
を読んで、から読んでください。それから一秒かそこら寝て、それらすべてをもう一度読んでください。これで、サンプリング時間中のプロセスのCPU使用率を次のように計算できます。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);
わかる?
私のような初心者のための簡単なステップ:
/proc/stat
を取得しますtotal_cpu_usage1
。 sscanf(line,"%*s %llu %llu %llu %llu",&user,&nice,&system,&idle);
total_cpu_usage1 = user + nice + system + idle;
/proc/pid/stat
どこにあるかを読み取ります。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
しsystemtime
て取得するproc_times1
total_cpu_usage2
てproc_times2
式は次のとおりです。
(number of processors) * (proc_times2 - proc_times1) * 100 / (float) (total_cpu_usage2 - total_cpu_usage1)
から CPU の量を取得できます/proc/cpuinfo
。
プロセスのユーザー + カーネル CPU 使用率を計算するために、cafs の回答に基づいて 2 つの小さな C 関数を作成しました 。
詳細については、procのマンページを読むことができますが、要約すると、/ proc / [number] / statを読んで、プロセスに関する情報を取得できます。これは、「ps」コマンドでも使用されます。
すべてのフィールドとそのscanf形式指定子は、procmanpageに文書化されています。
コピーされたマンページからの情報の一部を次に示します(かなり長いです)。
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.
「pidstat」コマンドを見てください。まさに必要なもののように聞こえます。
これが私の解決策です...
/*
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
これを proc から解析する代わりに、getrusage() や clock_gettime() などの関数を使用して、CPU 使用率を比率またはウォールクロック時間として計算し、プロセス/スレッドが 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
.
.
.