CPU使用率的计算方法

Windows下,大家可以使用任务理器来查看系统的各种资源使用情况,我们常常比较关心的就是CPU使用率,在Linux,同样有这样可视化的软件,但是大家可能会好奇那些不断变化的数字是怎样计算出来的?
下面,我就来分析一下psutil是怎样计算CPU的使用率的。
简单介绍一下psutil,psutil是一个python获取当前系统资源的第三方模块,可以跨平台的获取系统的各方面资源。
psutil获取系统cpu使用率的方法是cpu_percent(),其有两个参数,分别是interval和percpu,interval指定的是计算cpu使用率的时间间隔,percpu则指定是选择总的使用率还是每个cpu的使用率
描述系统cpu使用情况主要有一下几点:

user          从系统启动到现在,CPU处于用户态的运行时间。不包含nice值为负的进程。
nice          从系统启动到现在,CPUnice为负值的进程占用的cpu时间
system        从系统启动到现在,CPU处于内核态的运行时间
idle          从系统启动到现在,CPU除了 iowait外的等待时间
iowait        从系统启动到现在,CPUio 等待时间
irq           从系统启动到现在,CPU硬中断花费的时间
softirq       从系统启动到现在,CPU软中断花费的时间
steal         从系统启动到现在,CPU运行其他虚拟环境中的操作系统花费的时间
guest         从系统启动到现在,CPU运行在通过Linux内核控制的客户操作系统上的虚拟cpu的时间
guest_nice    从系统启动到现在,CPU运行在通过Linux内核控制的客户操作系统上的虚拟cpu的时间, nice 为负值进程

知道了以上参数的意思,计算某段时间内的cpu使用率就不难,由于cpu资源是在高速的变化,于是计算cpu使用率只能是在一段时间内的,设置两个时间点为t1和t2,
CPU在t1和t2时间内总的使用时间:( user2+ nice2+ system2+ idle2+ iowait2+ irq2+ softirq2 + steal2 + guest2 + guest_nice2 ) - ( user1+ nice1+ system1+ idle1+ iowait1+ irq1+ softirq1 + steal1 + guest1 + guest_nice1)
CPU的空闲时间:(idle2 -idle1)
CPU在t1和t2时间内的使用率=CPU非空闲时间/CPU总时间*100%=(1-CPU的空闲时间/CPU总时间)*100%
则:
    CPU(t1,t2)使用率:1-(idle2-idle1)/(( user2+ nice2+ system2+ idle2+ iowait2+ irq2+ softirq2 + steal2 + guest2 + guest_nice2 ) - ( user1+ nice1+ system1+ idle1+ iowait1+ irq1+ softirq1 + steal1 + guest1 + guest_nice1))


简单了解了使用率的计算方法,下面我们看一下cpu_percent是怎样实现的

def cpu_percent(interval=None, percpu=False):
    """Return a float representing the current system-wide utilization as a percentage.
    返回一个当前系统cpu使用率的百分比结果,


    When interval is > 0.0 compares system CPU times elapsed before
    and after the interval (blocking).
    
    当interval大于0.0时,返回的是在这段时间内CUP的使用率


    When interval is 0.0 or None compares system CPU times elapsed
    since last call or module import, returning immediately (non
    blocking). That means the first time this is called it will
    return a meaningless 0.0 value which you should ignore.
    In this case is recommended for accuracy that this function be
    called with at least 0.1 seconds between calls.


    当interval是0.0或者是None时,系统在调用此模块后,还没来得及运行就立即返回了,返回的是没有任何意义的0,你应该忽略调这个值,为避免这种情况,为了准确,调用这个模块时间至少为0.1秒
    
    When percpu is True returns a list of floats representing the
    utilization as a percentage for each CPU.
    First element of the list refers to first CPU, second element
    to second CPU and so on.
    The order of the list is consistent across calls.


    当percpu的值为True时,则返回的是一个列表,里面包含每个CPU在该段时间内的CPU使用率
    
    Examples:


      >>> # blocking, system-wide
      >>> psutil.cpu_percent(interval=1)
      2.0
      >>>
      >>> # blocking, per-cpu
      >>> psutil.cpu_percent(interval=1, percpu=True)
      [2.0, 1.0]
      >>>
      >>> # non-blocking (percentage since last call)
      >>> psutil.cpu_percent(interval=None)
      2.9
      >>>
    """
    global _last_cpu_times  #全局变量,用于表示上一个时间点cpu的各项参数,用于和下一个时间点cpu各项参数进行计算
    global _last_per_cpu_times #全局变量,用于表示上一个时间点,各个cpu在上一个时间点的各项cpu参数,作用同上
    
    
    blocking = interval is not None and interval > 0.0 #判断interval的值,如果interval 不为空且大余0.0,则blocking值为真,否则为假




    def calculate(t1, t2):  #计算CPU使用率
        t1_all = sum(t1) #计算t1时间,cpu的使用时间,为各项参数的和
        t1_busy = t1_all - t1.idle #计算cpu的非空闲时间


        t2_all = sum(t2) #计算t1时间,cpu的使用时间,为各项参数的和
        t2_busy = t2_all - t2.idle #计算cpu的非空闲时间


        # this usually indicates a float precision issue
        if t2_busy <= t1_busy:  #如果t2时刻的非空闲时间小余t1时刻的,则直接返回0.0
            return 0.0


        busy_delta = t2_busy - t1_busy  #计算t1-t2时间段内CPU总的非空闲时间
        all_delta = t2_all - t1_all     #计算t1-t2时间段内CPU总的使用时间
        busy_perc = (busy_delta / all_delta) * 100  #计算t1-t2时间段内CPU总的使用率
        return round(busy_perc, 1) #保留一位小数后返回


    # system-wide usage
    if not percpu:   #如果percpu为False
        if blocking: #interval 不为空且大余0.0
            t1 = cpu_times() #获取t1时刻,cpu各项参数
            time.sleep(interval) #休眠interval时间
        else:
            t1 = _last_cpu_times #如果不满足interval 不为空且大余0.0
            if t1 is None:  #当interval为None
                # Something bad happened at import time. We'll
                # get a meaningful result on the next call. See:
                # https://github.com/giampaolo/psutil/pull/715
                t1 = cpu_times()


        #当interval为None,_last_cpu_times与t1几乎是在同一时刻计算的,值几乎相同,因此将返回0.0
        _last_cpu_times = cpu_times()
        return calculate(t1, _last_cpu_times)
    # per-cpu usage
    else:
        ret = []
        if blocking:
            tot1 = cpu_times(percpu=True)
            time.sleep(interval)
        else:
            tot1 = _last_per_cpu_times
            if tot1 is None:
                # Something bad happened at import time. We'll
                # get a meaningful result on the next call. See:
                # https://github.com/giampaolo/psutil/pull/715
                tot1 = cpu_times(percpu=True)
        _last_per_cpu_times = cpu_times(percpu=True)
        for t1, t2 in zip(tot1, _last_per_cpu_times):
            ret.append(calculate(t1, t2)) #循环计算各个CPU的使用率
        return ret




# Use separate global vars for cpu_times_percent() so that it's
# independent from cpu_percent() and they can both be used within
# the same program.
_last_cpu_times_2 = _last_cpu_times
_last_per_cpu_times_2 = _last_per_cpu_times




  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值