Linux系统环境cpu利用率统计原理分析及使用python脚本统计cpu利用率

Linux统计cpu利用率

  • 简介: 本文主要是介绍Linux环境下cpu利用率统计原理,并使用python脚本来统计一个时间段内的cpu利用率。
  • 环境:本文的脚本都是运行于Centos7环境下,其他Centos版本或者ubuntu版本可能不适用

一、/proc文件系统的介绍

/proc文件系统是一个伪文件系统,它只存在内存当中,而不占用外存空间。它以文件系统的方式为内核与进程提供通信的接口。用户和应用程序可以通过/proc得到系统的信息,并可以改变内核的某些参数。

  1. /proc/cpuinfo文件(cpu相关信息)
  2. /proc/stat文件(所有cpu活动信息)
  3. /proc/pid/stat文件(进程相关信息)
    • pid(进程ID)
    • utime(该任务用户态运行时间)
    • stime(核心态运行时间)
    • cutime(所有已死线程用户态运行时间)
    • cstime(所有已死线程和心态运行时间)
    • 进程cpu总时间 = utime + stime + cutime + cstime
      (单位是jiffies)
  4. /proc/pid/task/tid/stat文件 (线程相关信息)
    • tid
    • 线程cpu总时间 = utime + stime
  5. ps命令
    • ps命令算出来的cpu使用率相对于进程启动时的平均值,随着进程运行时间的增大,该值会趋向于平缓。
  6. top命令
  7. 单核情况下Cpu使用率的计算
  8. 总的Cpu使用率计算
  9. 某一进程Cpu使用率的计算
  10. 多核情况下cpu使用率的计算

二、各资源利用率的计算

  1. Linux计算cpu利用率

    • cat /proc/stat |grep cpu
    • 大概有9-10列信息,不同系统显示的列数不一样。
    • 第一行是其他行数据的总和
    • 每列从左到右分别表示(如下图所示)(单位为jiffies):
      • user:从系统启动开始累计到当前时刻,用户态的cpu时间(不包含nice值为负的进程所占用的cpu时间)
      • nice:从系统启动开始累计到当前时刻,ncie为负的进程所占用的cpu时间
      • system: 从系统启动开始累计到当前时刻,内核态所占用的cpu时间
      • idle: 从系统启动开始累计到当前时刻,除IO等待时间以外的其它等待时间(cpu空闲时间)
      • iowait:从系统启动开始累计到当前时刻,等待IO的时间
      • irq: 从系统启动开始累计到当前时刻,系统中的硬中断时间
      • softirq: 从系统启动开始累计到当前时刻,系统中的软中断时间
        在这里插入图片描述
        图中显示了该机器有20核,cpu 行的数据 (代表20个cpu总使用量)是cpu0-19各行数据的总和
        注意:jiffies是内核中的一个全局变量,用来记录自系统启动一来产生的节拍数,在linux中,一个节拍大致可理解为操作系统进程调度的最小时间片,不同linux内核可能值有不同,通常在1ms到10ms之间
    • t1-t2时间内的总CPU时间: total = t2时刻第一行每列之和-t1时刻的第一行每列之和
      def get_system_cpu_usage():
      """获取时刻t系统的CPU使用情况"""
      with open('/proc/stat') as f:
          lines = f.readlines()
      usage = 0
      # for line in lines:
      #     if 'cpu' in line:
      #         line = line.split("\n")[0].split(' ')
      #         usage += sum([float(l) for l in line[1:] if l])
      #         print(line)
      usage += sum([int(i) for i in lines[0].split('\n')[0].split(' ')[1:] if i])
      print(usage)
      logging.debug("System_CPU_Usage:{}".format(usage))
      return usage
      
      在这里插入图片描述
      时刻t cpu使用量为cpu行中各列数值之和,即 usage=246270275+486352+ 。。。
    • t1-t2时刻每核CPU时间 = t2时刻第一列除第一行以外的各行 - t1时刻第一列除第一行以外的各行
      def get_system_usage_per_cpu():
      """获取系统的每个CPU使用情况"""
      with open('/proc/stat') as f:
          lines = f.readlines()
      usage_per_cpu = 0
      cpu_list = [line for line in lines[1:] if 'cpu' in line]
      per_cpu_list = []
      idle_list = []
      for cpu in cpu_list:
          row = cpu.split('\n')[0].split(' ')
          idle_list.append(int(row[4]))
          usage_per_cpu += sum([int(i)for i in row[1:] if i])
          per_cpu_list.append(usage_per_cpu)
          usage_per_cpu = 0
      # print(idle_list)
      # print(per_cpu_list)
      return idle_list, per_cpu_list
      
    • t1-t2时间内的CPU空闲时间:idle = idle(t2)-idle(t1)
      def get_system_idle_of_cpu():
          """获取系统的cpu空闲时间总量"""
          with open('/proc/stat') as f:
              line = f.readline()
          return line.split(' ')[5]
      
      在这里插入图片描述
      line.split(" ")出来的列表中间多了一个空格,所以取的是[5],正常的是idle在第4列
    • t1-t2时间内cpu利用率:per_cpu = (total-idle)/total*100
      def get_cpu_usage_and_idle():
          """获取cpu总量和idle,返回(cpu_usage,idle)"""
          with open("/proc/stat") as f:
              line = f.readline()
          line = line.split(' ')
          return line[2], line[5]
      t1 = get_cpu_usage_and_idle() 
      t2 = get_cpu_usage_and_idle()
      total = t2[0]-t1[0]
      idle = t2[1] - t1[1]
      cpu_percentage = (total-idle)/total*100
      
      
  2. 计算内存的利用率

    • 文件/proc/meminfo存放内存的相关信息
    • cat /proc/meminfo查看内存相关信息
    • 内存使用总量计算:
      • used = total - free - buffers -cached
        在这里插入图片描述
        内存的数据比较清晰,这里不做太多的解释了
  3. 计算网络使用信息

    • /proc/net/dev
    • 读取网卡的发送和收取信息的总字节数,一般为eth0,多网卡多IP的情况下需要读取多块网卡的收发信息总字节数
  4. 获取网卡的IP地址和主机的cpu个数。

发布了31 篇原创文章 · 获赞 16 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/Urms_handsomeyu/article/details/88261785