监视每个用户的CPU总时间最公平的方法是什么?


25

在多用户系统上,我想以cpu时间的秒数衡量每个用户的CPU使用率。出于此测量的目的,我假设如果PID属于某个用户,则该用户正在导致CPU时间-也就是说,我忽略了守护进程和内核。

目前,我每五秒钟执行一次:

  1. 获取每个用户及其正在运行的PID ps aux
  2. 对于每一个PID,得到x的总和,UTIME,cutime,STIME和cstime从/proc/[pid]/stat
  3. 计算t = x / interval(高负载时间隔并不总是精确地为5秒)

如果运行此命令,则将获得明智的外观值。例如:该系统上的一个用户正在使用python(while True: pass)旋转,并且该系统每秒显示大约750毫秒的CPU时间。当系统挂起一会儿时,它报告了1600毫秒,时间间隔为1秒。这似乎是正确的,但我已了解,这些值可以是deceiptful,特别是考虑到我并不真正了解他们。

所以我的问题是这样的:

有一种公平,正确的方法来按用户衡量CPU负载?

该方法必须相当准确。该系统上可能有数百个用户,因此从中提取百分比ps aux将不够准确,尤其是对于许多软件喜欢生成的短寿命线程。

尽管这可能很复杂,但我绝对知道这是可能的。这是我的出发点:

内核跟踪进程的创建时间以及它在生命周期中消耗的CPU时间。每次时钟滴答,内核都会以当前时间更新系统和用户模式所花费的时间。—(来自Linux Documentation Project

我要输入的值是用户在CPU上花费的秒数(秒),而不是系统负载或cpu使用率的百分比。

重要的是,我们在进程仍在运行时测量CPU时间。有些进程将仅持续半秒,有些进程将持续数月-我们需要同时捕获这两种类型,以便我们能够以精细的粒度考虑用户的CPU时间。


1
500声望:初学者的好机会
Tachyons

有点脱离我的联盟了,但是这是一个非常有趣的问题,所以我挖了一点,发现我希望至少可以帮助您解决此问题的东西:stackoverflow.com/a/1424556/905573
kingmilo 2012年

1
你知道top可以做批处理模式吗?top -b -n 1 -u {user} | awk 'NR>7 { sum += $9; } END { print sum; }'此时应显示{user}的负载。
Rinzwind'3

Answers:


11

听起来您需要流程记帐。

http://www.faqs.org/docs/Linux-mini/Process-Accounting.html

在Ubuntu上,过程会计工具位于acct软件包中 安装帐户

要获取每个用户的报告,请运行

sa -m

不幸的是,这对我不起作用,因为“ sa”将不计入长期运行的过程。我需要(我认为)是一种检测进程正在启动和终止,并记录其退出时以及运行时的CPU时间的方法。
Stefano Palazzo

@StefanoPalazzo我相信这是最好的。使用时间来增强它的运行速度/proc/[pid]/stat
ændrük

事实证明,似乎大多数所有进程都将由sa(.ps.gz)正确处理。而且,在最终为这些长期运行的流程获得准确价值之前,我还有一种很好的方法来“估算”这些长期运行的流程。因此,我们毕竟会使用它,我很乐意为您的答案提供赏金。谢谢一群!
Stefano Palazzo

3

这将为每个用户显示一行,显示用户名及其总CPU时间:

ps -w -e --no-header -o uid,user \
        | sort -u \
        | while read uid user; do
                echo -e "$user\t"$(
                        ps --no-headers -u $uid --cumulative -o time \
                                | sed -e s/:/*3600+/ -e s/:/*60+/ \
                                | paste -sd+ \
                                | bc
                );
        done


0

这还将处理已经运行了数天的流程。不确定如何扩展数周/月/年。

ps -w -e --no-header -o uid,user \
    | sort -u \
    | while read uid user; do
            echo -e "$user\t"$(
                    ps --no-headers -u $uid --cumulative -o time \
                          | sed -e s/-/*86400+/ -e s/:/*3600+/ -e s/:/*60+/ 
                          | paste -sd+ \
                          | bc
            );
    done
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.