Table of Contents
need
solution
expand
refer to
Home System Tutorial LINUX Detailed explanation of the case of calculating specific CPU usage in Linux

Detailed explanation of the case of calculating specific CPU usage in Linux

Dec 22, 2023 am 10:34 AM
linux calculate cpu usage Linux calculates specific cpu usage

Calculating specific CPU usage in Linux Requirements solution expansion reference

need

In Linux, you can use the top command to check the CPU occupied by a certain process, or you can check the usage of a certain CPU (first top command, then press the number "1" key to display the usage of each CPU) ,As shown below:

Detailed explanation of the case of calculating specific CPU usage in Linux

And our requirement is: How to get a CPU occupancy rate?

solution

1. Background knowledge

You can check the usage of each CPU in /proc/stat, as shown below:

Detailed explanation of the case of calculating specific CPU usage in Linux

The meaning of the ten numbers after cpu (0/1/2/…) is as follows:

/proc/stat
kernel/system statistics.  Varies with architecture.  
Common entries include:

     user nice system idle iowait  irq  softirq steal guest guest_nice
cpu  4705 356  584    3699   23    23     0       0     0        0
cpu0 1393280 32966 572056 13343292 6130 0 17875 0 23933 0
   The amount of time, measured in units of USER_HZ
   (1/100ths of a second on most architectures, use
   sysconf(_SC_CLK_TCK) to obtain the right value), that
   the system ("cpu" line) or the specific CPU ("cpuN"
   line) spent in various states:

   user   (1) Time spent in user mode.

   nice   (2) Time spent in user mode with low priority
          (nice).

   system (3) Time spent in system mode.

   idle   (4) Time spent in the idle task.  This value
          should be USER_HZ times the second entry in the
          /proc/uptime pseudo-file.

   iowait (since Linux 2.5.41)
          (5) Time waiting for I/O to complete.  This
          value is not reliable, for the following rea‐
          sons:

          1. The CPU will not wait for I/O to complete;
             iowait is the time that a task is waiting for
             I/O to complete.  When a CPU goes into idle
             state for outstanding task I/O, another task
             will be scheduled on this CPU.

          2. On a multi-core CPU, the task waiting for I/O
             to complete is not running on any CPU, so the
             iowait of each CPU is difficult to calculate.

          3. The value in this field may decrease in cer‐
             tain conditions.

   irq (since Linux 2.6.0-test4)
          (6) Time servicing interrupts.

   softirq (since Linux 2.6.0-test4)
          (7) Time servicing softirqs.

   steal (since Linux 2.6.11)
          (8) Stolen time, which is the time spent in
          other operating systems when running in a virtu‐
          alized environment

   guest (since Linux 2.6.24)
          (9) Time spent running a virtual CPU for guest
          operating systems under the control of the Linux
          kernel.

   guest_nice (since Linux 2.6.33)
          (10) Time spent running a niced guest (virtual
          CPU for guest operating systems under the con‐
          trol of the Linux kernel).
Copy after login

2. Calculate specific CPU usage

With the above background knowledge, we can then calculate the specific CPU usage. The specific calculation method is as follows:

Total CPU time since boot = user+nice+system+idle+iowait+irq+softirq+steal
Total CPU Idle time since boot = idle + iowait
Total CPU usage time since boot = Total CPU time since boot - Total CPU Idle time since boot
Total CPU percentage = Total CPU usage time since boot/Total CPU time since boot * 100%
Copy after login

With the above calculation formula, it is not difficult to calculate a certain CPU usage or the total CPU usage of the system.
Example: Calculate the overall CPU usage of the system
First, get the overall user, nice, system, idle, iowait, irq, softirq, steal, guest, guest_nice values ​​of the system at t1 from /proc/stat, and get the Total CPU time since boot ( Denoted as total1) and Total CPU idle time since boot (denoted as idle1).
Secondly, obtain the total Total CPU time since boot (recorded as total2) and Total CPU idle time since boot (recorded as idle2) of the system at time t2 from /proc/stat. (The method is the same as the previous step)
Finally, calculate the total CPU usage of the system between t2 and t1. That is:
CPU percentage between t1 and t2 = ((total2-total1)-(idle2-idle1))/(total2-total1)* 100%
Among them, ((total2-total1)-(idle2-idle1)) is actually the time that the system CPU is occupied between t1 and t2 (total time - idle time).
The following is a script that calculates CPU usage within a period of time:

#!/bin/bash
# by Paul Colby (http://colby.id.au), no rights reserved ;)

PREV_TOTAL=0
PREV_IDLE=0

while true; do
  # Get the total CPU statistics, discarding the 'cpu ' prefix.
  CPU=(`sed -n 's/^cpu\s//p' /proc/stat`)
  IDLE=${CPU[3]} # Just the idle CPU time.

  # Calculate the total CPU time.
  TOTAL=0
  for VALUE in "${CPU[@]}"; do
    let "TOTAL=$TOTAL+$VALUE"
  done

  # Calculate the CPU usage since we last checked.
  let "DIFF_IDLE=$IDLE-$PREV_IDLE"
  let "DIFF_TOTAL=$TOTAL-$PREV_TOTAL"
  let "DIFF_USAGE=(1000*($DIFF_TOTAL-$DIFF_IDLE)/$DIFF_TOTAL+5)/10"
  echo -en "\rCPU: $DIFF_USAGE%  \b\b"

  # Remember the total and idle CPU times for the next check.
  PREV_TOTAL="$TOTAL"
  PREV_IDLE="$IDLE"

  # Wait before checking again.
  sleep 1
done
Copy after login

expand

In the kernel, the implementation functions for files in /proc/stat are as follows:

附注:内核版本3.14.69,文件为 /fs/proc/stat.c

#include <linux/cpumask.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/kernel_stat.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/irqnr.h>
#include <asm/cputime.h>
#include <linux/tick.h>

#ifndef arch_irq_stat_cpu
#define arch_irq_stat_cpu(cpu) 0
#endif
#ifndef arch_irq_stat
#define arch_irq_stat() 0
#endif

#ifdef arch_idle_time

static cputime64_t get_idle_time(int cpu)
{
	cputime64_t idle;

	idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
	if (cpu_online(cpu) && !nr_iowait_cpu(cpu))
		idle += arch_idle_time(cpu);
	return idle;
}

static cputime64_t get_iowait_time(int cpu)
{
	cputime64_t iowait;

	iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT];
	if (cpu_online(cpu) && nr_iowait_cpu(cpu))
		iowait += arch_idle_time(cpu);
	return iowait;
}

#else

static u64 get_idle_time(int cpu)
{
	u64 idle, idle_time = -1ULL;

	if (cpu_online(cpu))
		idle_time = get_cpu_idle_time_us(cpu, NULL);

	if (idle_time == -1ULL)
		/* !NO_HZ or cpu offline so we can rely on cpustat.idle */
		idle = kcpustat_cpu(cpu).cpustat[CPUTIME_IDLE];
	else
		idle = usecs_to_cputime64(idle_time);

	return idle;
}

static u64 get_iowait_time(int cpu)
{
	u64 iowait, iowait_time = -1ULL;

	if (cpu_online(cpu))
		iowait_time = get_cpu_iowait_time_us(cpu, NULL);

	if (iowait_time == -1ULL)
		/* !NO_HZ or cpu offline so we can rely on cpustat.iowait */
		iowait = kcpustat_cpu(cpu).cpustat[CPUTIME_IOWAIT];
	else
		iowait = usecs_to_cputime64(iowait_time);

	return iowait;
}

#endif

static int show_stat(struct seq_file *p, void *v)
{
	int i, j;
	unsigned long jif;
	u64 user, nice, system, idle, iowait, irq, softirq, steal;
	u64 guest, guest_nice;
	u64 sum = 0;
	u64 sum_softirq = 0;
	unsigned int per_softirq_sums[NR_SOFTIRQS] = {0};
	struct timespec boottime;

	user = nice = system = idle = iowait =
		irq = softirq = steal = 0;
	guest = guest_nice = 0;
	getboottime(&boottime);
	jif = boottime.tv_sec;

	for_each_possible_cpu(i) {
		user += kcpustat_cpu(i).cpustat[CPUTIME_USER];
		nice += kcpustat_cpu(i).cpustat[CPUTIME_NICE];
		system += kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
		idle += get_idle_time(i);
		iowait += get_iowait_time(i);
		irq += kcpustat_cpu(i).cpustat[CPUTIME_IRQ];
		softirq += kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ];
		steal += kcpustat_cpu(i).cpustat[CPUTIME_STEAL];
		guest += kcpustat_cpu(i).cpustat[CPUTIME_GUEST];
		guest_nice += kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE];
		sum += kstat_cpu_irqs_sum(i);
		sum += arch_irq_stat_cpu(i);

		for (j = 0; j < NR_SOFTIRQS; j++) {
			unsigned int softirq_stat = kstat_softirqs_cpu(j, i);

			per_softirq_sums[j] += softirq_stat;
			sum_softirq += softirq_stat;
		}
	}
	sum += arch_irq_stat();

	seq_puts(p, "cpu ");
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(user));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(nice));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(system));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(idle));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iowait));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(irq));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(softirq));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
	seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
	seq_putc(p, '\n');

	for_each_online_cpu(i) {
		/* Copy values here to work around gcc-2.95.3, gcc-2.96 */
		user = kcpustat_cpu(i).cpustat[CPUTIME_USER];
		nice = kcpustat_cpu(i).cpustat[CPUTIME_NICE];
		system = kcpustat_cpu(i).cpustat[CPUTIME_SYSTEM];
		idle = get_idle_time(i);
		iowait = get_iowait_time(i);
		irq = kcpustat_cpu(i).cpustat[CPUTIME_IRQ];
		softirq = kcpustat_cpu(i).cpustat[CPUTIME_SOFTIRQ];
		steal = kcpustat_cpu(i).cpustat[CPUTIME_STEAL];
		guest = kcpustat_cpu(i).cpustat[CPUTIME_GUEST];
		guest_nice = kcpustat_cpu(i).cpustat[CPUTIME_GUEST_NICE];
		seq_printf(p, "cpu%d", i);
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(user));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(nice));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(system));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(idle));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(iowait));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(irq));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(softirq));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(steal));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest));
		seq_put_decimal_ull(p, ' ', cputime64_to_clock_t(guest_nice));
		seq_putc(p, '\n');
	}
	seq_printf(p, "intr %llu", (unsigned long long)sum);

	/* sum again ? it could be updated? */
	for_each_irq_nr(j)
		seq_put_decimal_ull(p, ' ', kstat_irqs_usr(j));

	seq_printf(p,
		"\nctxt %llu\n"
		"btime %lu\n"
		"processes %lu\n"
		"procs_running %lu\n"
		"procs_blocked %lu\n",
		nr_context_switches(),
		(unsigned long)jif,
		total_forks,
		nr_running(),
		nr_iowait());

	seq_printf(p, "softirq %llu", (unsigned long long)sum_softirq);

	for (i = 0; i < NR_SOFTIRQS; i++)
		seq_put_decimal_ull(p, ' ', per_softirq_sums[i]);
	seq_putc(p, '\n');

	return 0;
}

static int stat_open(struct inode *inode, struct file *file)
{
	size_t size = 1024 + 128 * num_possible_cpus();
	char *buf;
	struct seq_file *m;
	int res;

	/* minimum size to display an interrupt count : 2 bytes */
	size += 2 * nr_irqs;

	/* don't ask for more than the kmalloc() max size */
	if (size > KMALLOC_MAX_SIZE)
		size = KMALLOC_MAX_SIZE;
	buf = kmalloc(size, GFP_KERNEL);
	if (!buf)
		return -ENOMEM;

	res = single_open(file, show_stat, NULL);
	if (!res) {
		m = file->private_data;
		m->buf = buf;
		m->size = ksize(buf);
	} else
		kfree(buf);
	return res;
}

static const struct file_operations proc_stat_operations = {
	.open		= stat_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static int __init proc_stat_init(void)
{
	proc_create("stat", 0, NULL, &proc_stat_operations);
	return 0;
}
fs_initcall(proc_stat_init);
Copy after login

refer to

http://man7.org/linux/man-pages/man5/proc.5.html

https://www.php.cn/link/f45cc474bff52cb1b2268a2f94a2abcf

https://www.php.cn/link/73d02e4344f71a0b0d51a925246990e7

The above is the detailed content of Detailed explanation of the case of calculating specific CPU usage in Linux. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: How To Unlock Everything In MyRise
1 months ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Mastering Text Manipulation With the Sed Command Mastering Text Manipulation With the Sed Command Mar 16, 2025 am 09:48 AM

The Linux command line interface provides a wealth of text processing tools, one of the most powerful tools is the sed command. sed is the abbreviation of Stream EDitor, a multi-functional tool that allows complex processing of text files and streams. What is Sed? sed is a non-interactive text editor that operates on pipeline inputs or text files. By providing directives, you can let it modify and process text in a file or stream. The most common use cases of sed include selecting text, replacing text, modifying original files, adding lines to text, or removing lines from text. It can be used from the command line in Bash and other command line shells. Sed command syntax sed

How To Count Files And Directories In Linux: A Beginner's Guide How To Count Files And Directories In Linux: A Beginner's Guide Mar 19, 2025 am 10:48 AM

Efficiently Counting Files and Folders in Linux: A Comprehensive Guide Knowing how to quickly count files and directories in Linux is crucial for system administrators and anyone managing large datasets. This guide demonstrates using simple command-l

How To Add A User To Multiple Groups In Linux How To Add A User To Multiple Groups In Linux Mar 18, 2025 am 11:44 AM

Efficiently managing user accounts and group memberships is crucial for Linux/Unix system administration. This ensures proper resource and data access control. This tutorial details how to add a user to multiple groups in Linux and Unix systems. We

How To List Or Check All Installed Linux Kernels From Commandline How To List Or Check All Installed Linux Kernels From Commandline Mar 23, 2025 am 10:43 AM

Linux Kernel is the core component of a GNU/Linux operating system. Developed by Linus Torvalds in 1991, it is a free, open-source, monolithic, modular, and multitasking Unix-like kernel. In Linux, it is possible to install multiple kernels on a sing

How To Type Indian Rupee Symbol In Ubuntu Linux How To Type Indian Rupee Symbol In Ubuntu Linux Mar 22, 2025 am 10:39 AM

This brief guide explains how to type Indian Rupee symbol in Linux operating systems. The other day, I wanted to type "Indian Rupee Symbol (₹)" in a word document. My keyboard has a rupee symbol on it, but I don't know how to type it. After

What is the Linux best used for? What is the Linux best used for? Apr 03, 2025 am 12:11 AM

Linux is best used as server management, embedded systems and desktop environments. 1) In server management, Linux is used to host websites, databases, and applications, providing stability and reliability. 2) In embedded systems, Linux is widely used in smart home and automotive electronic systems because of its flexibility and stability. 3) In the desktop environment, Linux provides rich applications and efficient performance.

Linux Kernel 6.14 RC6 Released Linux Kernel 6.14 RC6 Released Mar 24, 2025 am 10:21 AM

Linus Torvalds has released Linux Kernel 6.14 Release Candidate 6 (RC6), reporting no significant issues and keeping the release on track. The most notable change in this update addresses an AMD microcode signing issue, while the rest of the updates

The 8 Best SSH Clients for Linux The 8 Best SSH Clients for Linux Mar 15, 2025 am 11:06 AM

Recommended 8 best SSH clients for Linux system SSH (Secure Shell Protocol) is an encrypted network protocol used to securely run network services on an unsecure network. It is an important part of modern server management and provides secure remote access to the system. SSH clients (applications that utilize the SSH protocol) are an indispensable tool for system administrators, developers and IT professionals. Remote server management is common in the Linux world, and choosing the right SSH client is crucial. This article will discuss 8 best SSH clients for Linux. Selection criteria When choosing the best SSH client for Linux, the following factors must be considered: Performance: Speed ​​and efficiency of SSH clients

See all articles