linux内核获取滴答数,linux-如何从/ proc / pid / stat获取应用程序的总CPU使用率?

linux-如何从/ proc / pid / stat获取应用程序的总CPU使用率?

我想知道如何计算一个进程的总CPU使用率。

如果我做pid / stat,我认为相关字段是(摘自lindevdoc.org):

用户代码中花费的CPU时间(以吉比特为单位)

花费在内核代码中的CPU时间,以吉比特为单位

用户代码中花费的CPU时间,包括来自子代的时间

花费在内核代码上的CPU时间,包括来自子代的时间

那么总花费时间是14到17字段的总和?

alexwlchan asked 2020-01-08T16:04:10Z

6个解决方案

123 votes

制备

要计算特定进程的CPU使用率,您需要执行以下操作:

total_timetotal_time系统的正常运行时间(秒)

total_timetotal_time starttime-用户代码中花费的CPU时间(以时钟周期为单位)

total_time starttime-花费在内核代码中的CPU时间(以时钟周期为单位)

total_time starttime-用户代码中等待的儿童的CPU时间(以时钟滴答为单位)

total_time starttime-等待的孩子的CPU时间花费在内核代码上(以时钟滴答为单位)

total_time starttime-进程开始的时间,以时钟滴答为单位

系统的赫兹(每秒的时钟滴答数)。在大多数情况下,total_time可用于返回时钟滴答数。

C函数total_time还可用于返回赫兹值。

计算方式

首先,我们确定该过程花费的总时间:

total_time = utime + stime

我们还必须决定是否要包括子进程中的时间。 如果这样做,则将这些值添加到total_time:

total_time = total_time + cutime + cstime

接下来,我们获取自该过程开始以来经过的总时间(以秒为单位):

seconds = uptime - (starttime / Hertz)

最后,我们计算CPU使用率百分比:

cpu_usage = 100 * ((total_time / Hertz) / seconds)

也可以看看

top和ps没有显示相同的cpu结果

如何在Linux(C ++)中获得总的CPU使用率

在Linux中计算进程的CPU使用率

Vilhelm Gray answered 2020-01-08T16:05:52Z

6 votes

是的,你可以这么说。 您可以使用公式将这些值转换为秒:

sec = jiffies / HZ ; here - HZ = number of ticks per second

HZ值是可配置的-在内核配置时完成。

rakib_ answered 2020-01-08T16:06:16Z

3 votes

如果需要计算最近10秒内某个进程使用了多少cpu%

得到总时间(13 + 14)等于= t1启动时间(22)in jiffies => s1

-延迟10秒

总时间(13 + 14)等于=> t2启动时间(22)in jiffies => s2

t2-t1 * 100 / s2-s1不会给%??

answered 2020-01-08T16:06:54Z

2 votes

这是获取应用程序CPU使用率的另一种方法。 我是在Android上完成的,它调用了内核top,并使用top返回的值获取了应用程序PID的CPU使用率。

public void myWonderfulApp()

{

// Some wonderfully written code here

Integer lMyProcessID = android.os.Process.myPid();

int lMyCPUUsage = getAppCPUUsage( lMyProcessID );

// More magic

}

// Alternate way that I switched to. I found the first version was slower

// this version only returns a single line for the app, so far less parsing

// and processing.

public static float getTotalCPUUsage2()

{

try

{

// read global stats file for total CPU

BufferedReader reader = new BufferedReader(new FileReader("/proc/stat"));

String[] sa = reader.readLine().split("[ ]+", 9);

long work = Long.parseLong(sa[1]) + Long.parseLong(sa[2]) + Long.parseLong(sa[3]);

long total = work + Long.parseLong(sa[4]) + Long.parseLong(sa[5]) + Long.parseLong(sa[6]) + Long.parseLong(sa[7]);

reader.close();

// calculate and convert to percentage

return restrictPercentage(work * 100 / (float) total);

}

catch (Exception ex)

{

Logger.e(Constants.TAG, "Unable to get Total CPU usage");

}

// if there was an issue, just return 0

return 0;

}

// This is an alternate way, but it takes the entire output of

// top, so there is a fair bit of parsing.

public static int getAppCPUUsage( Integer aAppPID)

{

int lReturn = 0;

// make sure a valid pid was passed

if ( null == aAppPID && aAppPID > 0)

{

return lReturn;

}

try

{

// Make a call to top so we have all the processes CPU

Process lTopProcess = Runtime.getRuntime().exec("top");

BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(lTopProcess.getInputStream()));

String lLine;

// While we have stuff to read and we have not found our PID, process the lines

while ( (lLine = bufferedReader.readLine()) != null )

{

// Split on 4, the CPU % is the 3rd field .

// NOTE: We trim because sometimes we had the first field in the split be a "".

String[] lSplit = lLine.trim().split("[ ]+", 4);

// Don't even bother if we don't have at least the 4

if ( lSplit.length > 3 )

{

// Make sure we can handle if we can't parse the int

try

{

// On the line that is our process, field 0 is a PID

Integer lCurrentPID = Integer.parseInt(lSplit[0]);

// Did we find our process?

if (aAppPID.equals(lCurrentPID))

{

// This is us, strip off the % and return it

String lCPU = lSplit[2].replace("%", "");

lReturn = Integer.parseInt(lCPU);

break;

}

}

catch( NumberFormatException e )

{

// No op. We expect this when it's not a PID line

}

}

}

bufferedReader.close();

lTopProcess.destroy(); // Cleanup the process, otherwise you make a nice hand warmer out of your device

}

catch( IOException ex )

{

// Log bad stuff happened

}

catch (Exception ex)

{

// Log bad stuff happened

}

// if there was an issue, just return 0

return lReturn;

}

GR Envoy answered 2020-01-08T16:07:14Z

1 votes

这是我用BASH编写的简单解决方案。 它是通过procfs(例如“ top”或“ ps”)进行的linux / unix系统监视器和进程管理器。 有两个版本:简单单色(快速)和彩色版本(有点慢,但特别适用于监视进程状态)。 我按CPU使用率进行了排序。

[https://github.com/AraKhachatryan/top]

utime,stime,cutime,cstime,用于从/ proc / [pid] / stat文件获取cpu使用情况的开始时间。

也可以从/ proc / [pid] / stat文件获得的状态,ppid,优先级,好,num_threads个参数。

常驻参数和data_and_stack参数,用于获取内存使用情况,并从/ proc / [pid] / statm文件获取。

function my_ps

{

pid_array=`ls /proc | grep -E '^[0-9]+$'`

clock_ticks=$(getconf CLK_TCK)

total_memory=$( grep -Po '(?<=MemTotal:\s{8})(\d+)' /proc/meminfo )

cat /dev/null > .data.ps

for pid in $pid_array

do

if [ -r /proc/$pid/stat ]

then

stat_array=( `sed -E 's/(\([^\s)]+)\s([^)]+\))/\1_\2/g' /proc/$pid/stat` )

uptime_array=( `cat /proc/uptime` )

statm_array=( `cat /proc/$pid/statm` )

comm=( `grep -Po '^[^\s\/]+' /proc/$pid/comm` )

user_id=$( grep -Po '(?<=Uid:\s)(\d+)' /proc/$pid/status )

user=$( id -nu $user_id )

uptime=${uptime_array[0]}

state=${stat_array[2]}

ppid=${stat_array[3]}

priority=${stat_array[17]}

nice=${stat_array[18]}

utime=${stat_array[13]}

stime=${stat_array[14]}

cutime=${stat_array[15]}

cstime=${stat_array[16]}

num_threads=${stat_array[19]}

starttime=${stat_array[21]}

total_time=$(( $utime + $stime ))

#add $cstime - CPU time spent in user and kernel code ( can olso add $cutime - CPU time spent in user code )

total_time=$(( $total_time + $cstime ))

seconds=$( awk 'BEGIN {print ( '$uptime' - ('$starttime' / '$clock_ticks') )}' )

cpu_usage=$( awk 'BEGIN {print ( 100 * (('$total_time' / '$clock_ticks') / '$seconds') )}' )

resident=${statm_array[1]}

data_and_stack=${statm_array[5]}

memory_usage=$( awk 'BEGIN {print( (('$resident' + '$data_and_stack' ) * 100) / '$total_memory' )}' )

printf "%-6d %-6d %-10s %-4d %-5d %-4s %-4u %-7.2f %-7.2f %-18s\n" $pid $ppid $user $priority $nice $state $num_threads $memory_usage $cpu_usage $comm >> .data.ps

fi

done

clear

printf "\e[30;107m%-6s %-6s %-10s %-4s %-3s %-6s %-4s %-7s %-7s %-18s\e[0m\n" "PID" "PPID" "USER" "PR" "NI" "STATE" "THR" "%MEM" "%CPU" "COMMAND"

sort -nr -k9 .data.ps | head -$1

read_options

}

Ara answered 2020-01-08T16:07:52Z

-3 votes

这是您要找的东西:

//USER_HZ detection, from openssl code

#ifndef HZ

# if defined(_SC_CLK_TCK) \

&& (!defined(OPENSSL_SYS_VMS) || __CTRL_VER >= 70000000)

# define HZ ((double)sysconf(_SC_CLK_TCK))

# else

# ifndef CLK_TCK

# ifndef _BSD_CLK_TCK_ /* FreeBSD hack */

# define HZ 100.0

# else /* _BSD_CLK_TCK_ */

# define HZ ((double)_BSD_CLK_TCK_)

# endif

# else /* CLK_TCK */

# define HZ ((double)CLK_TCK)

# endif

# endif

#endif

该代码实际上来自cpulimit,但使用openssl代码段。

Savio Sena answered 2020-01-08T16:08:16Z

你可能感兴趣的:(linux内核获取滴答数)