【问题标题】:How do I read CPU "stats" in Java from an Android phone?如何从 Android 手机读取 Java 中的 CPU“统计信息”?
【发布时间】:2014-01-13 21:51:13
【问题描述】:

我正在尝试按内核计算 CPU 使用率,如果可能的话,也许是温度,并且通常找出我可以从 CPU 读取的内容。

我已经进行了一些搜索,并且我有一些返回内核数量的代码(请参阅How can you detect a dual-core cpu on an Android device from code?)。现在我试图弄清楚如何使用它来从这个链接(Get Memory Usage in Android)获取核心的 CPU 使用率。

唯一的问题是我对 Java/Android 有点陌生,所以我很难理解评论者想说什么。一条评论说您应该更改 idle1 和 cpu1 上的分隔符......我对 idle2 和 cpu2 做同样的事情吗?任何帮助将不胜感激,所以提前感谢您!

好的,现在我对自己在做什么有了更好的理解,但是我的 4 核测试板上的核心 2-4 的读数都为 0。有时,当我启动应用程序时,核心 2 有一个值 > 0,但在后续运行时(应用程序每秒更新一次值)它会返回 0。这是我目前拥有的代码,非常感谢!!!

    public double readUsage(int corenum) {
    int j=0;
    int coreVal = getNumCores();
    String[] toks;
    long idle1;
    long cpu1;
    long idle2;
    long cpu2;

    try {           
            RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
            String load = reader.readLine();
            reader.seek(0);
            while (j <= corenum){
                load = reader.readLine();
                j++;
            }
            j=0;
            toks = load.split(" ");

            if (corenum == 0) {
                idle1 = Long.parseLong(toks[5]);
                cpu1 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
                      + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);
            }

            else {
                idle1 = Long.parseLong(toks[4]);
                cpu1 = Long.parseLong(toks[1]) + Long.parseLong(toks[2]) + Long.parseLong(toks[3])
                        + Long.parseLong(toks[5]) + Long.parseLong(toks[6]) + Long.parseLong(toks[7]);
            }   

            try {
                 Thread.sleep(100);
            } catch (Exception e) {}

            reader.seek(0);
            while (j <= corenum){
                load = reader.readLine();
                j++;
            }
            j=0;
            reader.close();
            toks = load.split(" ");

            if (corenum == 0) {
                idle2 = Long.parseLong(toks[5]);
                cpu2 = Long.parseLong(toks[2]) + Long.parseLong(toks[3]) + Long.parseLong(toks[4])
                      + Long.parseLong(toks[6]) + Long.parseLong(toks[7]) + Long.parseLong(toks[8]);
            }

            else {
                idle2 = Long.parseLong(toks[4]);
                cpu2 = Long.parseLong(toks[1]) + Long.parseLong(toks[2]) + Long.parseLong(toks[3])
                        + Long.parseLong(toks[5]) + Long.parseLong(toks[6]) + Long.parseLong(toks[7]);
            }

           return (double)(cpu2 - cpu1) / ((cpu2 + idle2) - (cpu1 + idle1));

    } catch (IOException ex) {
        ex.printStackTrace();
    }

    return 9999999;
}

【问题讨论】:

    标签: java android


    【解决方案1】:

    您可以使用此答案中的代码:Get Memory Usage in Android

    如 cmets 中所述,您可以跳过第一行以获取每个核心的数据。

    根据下面的评论,您可以阅读文件的每一行并打印用法,然后按照提供的链接拆分行:

    public void printCpuUsages()
    {
        try
        {
            RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
            String load = reader.readLine();
            while (load != null)
            {
                Log.d("CPU", "CPU usage: " + load);
                load = reader.readLine();
            }
        }
        catch (IOException ex)
        {
            ex.printStackTrace();
        }
    }
    

    【讨论】:

    • 当你说“跳过第一行”时,你到底是什么意思?也许是因为我整天都在看这一切都错了,但我只是评论了 'RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");'部分和一堆错误弹出。你得原谅我的无聊,我是一个被扔进 CS 项目的 ECE!
    • 我会对该线程本身发表评论,但我没有足够的声誉。我想它缺乏对函数整体工作原理的理解,但我似乎无法让它做我想做的事
    • 道歉-那里的描述有点含糊。您要跳过的行位于 /proc/stat 文件本身中。典型文件可能包含:CPU 183549 10728 236016 3754379 7530 41 1013 0 0 0 0 0 0 0 CPU2 13602 1630 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 cpu3 4585 551 3341 1033458 770 0 2 0 0 0 您可以通过读取文件中的每一行而不是使用 reader.readLine() 读取第一行来获取所有内核的 CPU 使用率。有关 /proc/stat 的更多详细信息,请参见此处:linuxhowtos.org/System/procstat.htm
    • 非常感谢cfred,这帮助了很多!我现在唯一遇到的问题是我的测试板(有 4 个核心),核心 2、3 和 4 读取一个常数 0。我想这是原始问题,因为它与当我开始的时候。
    • @cfred 你能告诉我可以使用上面的代码找到每个进程 ID 的 cpu 使用情况
    【解决方案2】:

    尽管答案似乎是有效的,但我创建了一个小型解析器来帮助人们提取“proc/stat”的信息。可以在here找到文档。

    public class Cpu {
    private String name = "";
    private long cpu_user = 0;
    private long cpu_niced = 0;
    private long cpu_system = 0;
    private long cpu_idle = 0;
    private long cpu_iowait = 0;
    private long cpu_irq = 0;
    private long cpu_softirqs = 0;
    
    public Cpu(String name, long cpu_user, long cpu_niced, long cpu_system, long cpu_idle, long cpu_iowait, long cpu_irq, long cpu_softirqs) {
        this.name = name;
        this.cpu_user = cpu_user;
        this.cpu_niced = cpu_niced;
        this.cpu_system = cpu_system;
        this.cpu_idle = cpu_idle;
        this.cpu_iowait = cpu_iowait;
        this.cpu_irq = cpu_irq;
        this.cpu_softirqs = cpu_softirqs;
    }
    
    public long getCpuUser() {
        return cpu_user;
    }
    
    public long getCpuNiced() {
        return cpu_niced;
    }
    
    public long getCpuSystem() {
        return cpu_system;
    }
    
    public long getCpuIdle() {
        return cpu_idle;
    }
    
    public long getCpuIowait() {
        return cpu_iowait;
    }
    
    public long getCpuIrq() {
        return cpu_irq;
    }
    
    public long getCpuSoftirqs() {
        return cpu_softirqs;
    }
    
    public double getAverageIdlePercentage(){
        return ( cpu_idle * 100 ) / ( cpu_user + cpu_niced + cpu_system + cpu_idle + cpu_iowait + cpu_irq + cpu_softirqs );
    }
    
    public String getName() {
        return name;
    }
    
    public String toString(){
        String temp ="";
        temp+= name+ " ";
        temp+= cpu_user+ " ";
        temp+= cpu_niced+ " ";
        temp+= cpu_system+ " ";
        temp+= cpu_idle+ " ";
        temp+= cpu_iowait+ " ";
        temp+= cpu_irq+ " ";
        temp+= cpu_softirqs+ " ";
        return temp;
    }
    }
    
    public class StatFile {
    
    /**
     * The very first line "cpu" aggregates the numbers in all of the other "cpuN" lines.
     * These numbers identify the amount of time the CPU has spent performing different kinds of work. Time units are in USER_HZ or Jiffies (typically hundredths of a second).
     */
    private List<Cpu> cpus;
    /**
     * Counts of interrupts serviced since boot time, for each of the possible system interrupts. The first column is the total of all interrupts serviced; each subsequent column is the total for that particular interrupt.
     */
    private List<Long> interruptions;
    /**
     * The total number of context switches across all CPUs.
     */
    private long ctxt = 0;
    
    /**
     * The time at which the system booted
     */
    private Date btime;
    
    /**
     * The number of processes and threads created, which includes (but is not limited to) those created by calls to the fork() and clone() system calls.
     */
    private long processes = 0;
    
    /**
     *  The number of processes currently running on CPUs
     */
    private long procs_running = 0;
    
    /**
     * The number of processes currently blocked, waiting for I/O to complete
     */
    private long procs_blocked = 0;
    
    private List<Long> softirq;
    
    public StatFile(){
        cpus = new ArrayList<Cpu>();
        interruptions = new ArrayList<Long>();
        ctxt = 0;
        btime = new Date();
        processes = 0;
        procs_running = 0;
        procs_blocked = 0;
        softirq = new ArrayList<Long>();
    }
    
    public List<Cpu> getCpus() {
        return cpus;
    }
    
    public void setCpus(List<Cpu> cpus) {
        this.cpus = cpus;
    }
    
    public List<Long> getInterruptions() {
        return interruptions;
    }
    
    public void setInterruptions(List<Long> interruptions) {
        this.interruptions = interruptions;
    }
    
    public long getCtxt() {
        return ctxt;
    }
    
    public void setCtxt(long ctxt) {
        this.ctxt = ctxt;
    }
    
    public Date getBtime() {
        return btime;
    }
    
    public void setBtime(Date btime) {
        this.btime = btime;
    }
    
    public long getProcesses() {
        return processes;
    }
    
    public void setProcesses(long processes) {
        this.processes = processes;
    }
    
    public long getProcs_running() {
        return procs_running;
    }
    
    public void setProcs_running(long procs_running) {
        this.procs_running = procs_running;
    }
    
    public long getProcs_blocked() {
        return procs_blocked;
    }
    
    public void setProcs_blocked(long procs_blocked) {
        this.procs_blocked = procs_blocked;
    }
    
    public List<Long> getSoftirq() {
        return softirq;
    }
    
    public void setSoftirq(List<Long> softirq) {
        this.softirq = softirq;
    }
    }
    

    CpuUtils 类:

    public class CpuUtils {
    
     private static final String TAG = CpuUtils.class.getSimpleName();
    
     /**
     * Normal processes executing in user mode
     */
    private static final int CPU_USER=1;
    /**
     * Niced processes executing in user mode
     */
    private static final int CPU_NICE=2;
    /**
     * Processes executing in kernel mode
     */
    private static final int CPU_SYSTEM=3;
    /**
     * Twiddling thumbs
     */
    private static final int CPU_IDLE=4;
    /**
     * Waiting for I/O to complete
     */
    private static final int CPU_IOWAIT=5;
    /**
     * Servicing interrupts
     */
    private static final int CPU_IRQ=6;
    /**
     * Servicing softirqs
     */
    private static final int CPU_SOFTIRQS=7;
    
    public static StatFile parseStatsFile() {
        StatFile statFile = new StatFile();
        try {
            RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
            try {
                while (true) {
                    String load = reader.readLine();
                    //Avoid problem parsing doble space
                    if(load!=null) {
                        Log.d(TAG, "Stat: " + load);
                        load = load.replace("  ", " ");
                        String[] tokens = load.split(" ");
                        if (tokens[0].startsWith("cpu")) {
                            Cpu cpu = parseCpuTokens(tokens);
                            statFile.getCpus().add(cpu);
                        }
                        else if(tokens[0].startsWith("intr")){
                            for(int i=1; i<tokens.length; i++){
                                statFile.getInterruptions().add(Long.parseLong(tokens[i]));
                            }
                        }
                        else if(tokens[0].startsWith("ctxt")){
                            statFile.setCtxt(Long.parseLong(tokens[1]));
                        }
                        else if(tokens[0].startsWith("btime")){
                            //time is in seconds, therefore we need it in milliseconds
                            statFile.setBtime(new Date(Long.parseLong(tokens[1])*1000));
                        }
                        else if(tokens[0].startsWith("processes")){
                            statFile.setProcesses(Long.parseLong(tokens[1]));
                        }
                        else if(tokens[0].startsWith("procs_running")){
                            statFile.setProcs_running(Long.parseLong(tokens[1]));
                        }
                        else if(tokens[0].startsWith("procs_blocked")){
                            statFile.setProcs_blocked(Long.parseLong(tokens[1]));
                        }
                        else if(tokens[0].startsWith("softirq")){
                            for(int i=1; i<tokens.length; i++){
                                statFile.getSoftirq().add(Long.parseLong(tokens[i]));
                            }
                        }
                    }
                    else{
                        throw new EOFException("File end reached");
                    }
                }
            } catch (EOFException ex) {
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    reader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }catch (FileNotFoundException e){
            e.printStackTrace();
            throw new IllegalStateException("Unable to access the stats");
        }
    
        return statFile;
    }
    
    private static Cpu parseCpuTokens(String[] tokens){
        Cpu cpu = new Cpu(tokens[0],
                Long.parseLong(tokens[CPU_USER]),
                Long.parseLong(tokens[CPU_NICE]),
                Long.parseLong(tokens[CPU_SYSTEM]),
                Long.parseLong(tokens[CPU_IDLE]),
                Long.parseLong(tokens[CPU_IOWAIT]),
                Long.parseLong(tokens[CPU_IRQ]),
                Long.parseLong(tokens[CPU_SOFTIRQS]));
        return cpu;
    }
    }
    

    【讨论】:

      猜你喜欢
      • 2011-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-21
      相关资源
      最近更新 更多