【问题标题】:How to get usage of each cpu core on android如何在android上获取每个cpu核心的使用情况
【发布时间】:2012-07-31 11:49:09
【问题描述】:

我在 Android 上开发了一个显示许多有用信息的小部件。

我正在尝试修改此方法以返回一个 cpu 核心的使用百分比,以便获得每个核心的使用百分比!!!

在我的 HTC One X 上,我有“/proc/stat”:

cpu  183549 10728 236016 3754379 7530 41 1013 0 0 0
cpu0 141962 5990 196956 720894 3333 41 970 0 0 0
cpu1 23400 2550 23158 980901 2211 0 23 0 0 0
cpu2 13602 1637 12561 1019126 1216 0 18 0 0 0
cpu3 4585 551 3341 1033458 770 0 2 0 0 0

我用这个方法返回所有cpu核心的使用百分比。

public float readUsage() {
    try {

        RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
        String load = reader.readLine();


        String[] toks = load.split(" ");

        long idle1 = Long.parseLong(toks[5]);
        long 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]);

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

        reader.seek(0);
        load = reader.readLine();
        reader.close();

        toks = load.split(" ");

        long idle2 = Long.parseLong(toks[5]);
        long 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]);

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

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

    return 0;
} 

我正在尝试使用 cpu1,但它不起作用:

public float readUsageCPU0() {
    try {

        RandomAccessFile reader = new RandomAccessFile("/proc/stat", "r");
        reader.seek(0);
        String load = reader.readLine();
        load = reader.readLine();
        load = reader.readLine();


        String[] toks = load.split(" ");

        long idle1 = Long.parseLong(toks[5]);
        long 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]);

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

        reader.seek(0);
        load = reader.readLine();
        load = reader.readLine();
        load = reader.readLine();
        reader.close();

        toks = load.split(" ");

        long idle2 = Long.parseLong(toks[5]);
        long 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]);

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

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

    return 0;
}

这允许读取一行并且光标停留在行尾:

String load = reader.readLine();

所以,我尝试使用它两次以获得 CPU0 的使用,第三次获得 CPU1。 但是结果总是0或者100……我不明白!

我使用正确的方法吗? 我使用正确的文件吗? 这个结果正常吗?

请帮忙!!!

【问题讨论】:

    标签: android cpu multicore core


    【解决方案1】:
    public class CpuStat {
        private static final String TAG = "CpuUsage";
        private RandomAccessFile statFile;
        private CpuInfo mCpuInfoTotal;
        private ArrayList<CpuInfo> mCpuInfoList;
    
        public CpuStat() {
        }
    
        public void update() {
            try {           
                createFile();
                parseFile();
                closeFile();
            } catch (FileNotFoundException e) {
                statFile = null;
                Log.e(TAG, "cannot open /proc/stat: " + e);
            } catch (IOException e) {
                Log.e(TAG, "cannot close /proc/stat: " + e);
            }
        }
    
        private void createFile() throws FileNotFoundException {
            statFile = new RandomAccessFile("/proc/stat", "r");
        }
    
        public void closeFile() throws IOException {
            if (statFile != null)
                statFile.close();
        }
    
        private void parseFile() {
            if (statFile != null) {
                try {
                    statFile.seek(0);
                    String cpuLine = "";
                    int cpuId = -1;
                    do { 
                        cpuLine = statFile.readLine();
                        parseCpuLine(cpuId, cpuLine);
                        cpuId++;
                    } while (cpuLine != null);
                } catch (IOException e) {
                    Log.e(TAG, "Ops: " + e);
                }
            }
        }
    
        private void parseCpuLine(int cpuId, String cpuLine) {
            if (cpuLine != null && cpuLine.length() > 0) { 
                String[] parts = cpuLine.split("[ ]+");
                String cpuLabel = "cpu";
                if ( parts[0].indexOf(cpuLabel) != -1) {
                    createCpuInfo(cpuId, parts);
                }
            } else {
                Log.e(TAG, "unable to get cpu line");
            }
        }
    
        private void createCpuInfo(int cpuId, String[] parts) {
            if (cpuId == -1) {                      
                if (mCpuInfoTotal == null)
                    mCpuInfoTotal = new CpuInfo();
                mCpuInfoTotal.update(parts);
            } else {
                if (mCpuInfoList == null)
                    mCpuInfoList = new ArrayList<CpuInfo>();
                if (cpuId < mCpuInfoList.size())
                    mCpuInfoList.get(cpuId).update(parts);
                else {
                    CpuInfo info = new CpuInfo();
                    info.update(parts);
                    mCpuInfoList.add(info);
                }                               
            }
        }
    
        public int getCpuUsage(int cpuId) {
            update();
            int usage = 0;
            if (mCpuInfoList != null) {
                int cpuCount = mCpuInfoList.size();
                if (cpuCount > 0) {
                    cpuCount--;
                    if (cpuId == cpuCount) { // -1 total cpu usage
                        usage = mCpuInfoList.get(0).getUsage(); 
                    } else {
                        if (cpuId <= cpuCount)
                            usage = mCpuInfoList.get(cpuId).getUsage();
                        else
                            usage = -1;
                    }
                }
            }
            return usage;
        }
    
    
        public int getTotalCpuUsage() {
            update();           
            int usage = 0;
            if (mCpuInfoTotal != null)
                usage = mCpuInfoTotal.getUsage();
            return usage;
        }
    
    
        public String toString() {
            update();
            StringBuffer buf = new StringBuffer();
            if (mCpuInfoTotal != null) {
                buf.append("Cpu Total : ");
                buf.append(mCpuInfoTotal.getUsage());
                buf.append("%");
            }   
            if (mCpuInfoList != null) {
                for (int i=0; i < mCpuInfoList.size(); i++) {
                    CpuInfo info = mCpuInfoList.get(i); 
                    buf.append(" Cpu Core(" + i + ") : ");
                    buf.append(info.getUsage());
                    buf.append("%");
                    info.getUsage();
                }
            }           
            return buf.toString();
        }
    
        public class CpuInfo {
            private int  mUsage;            
            private long mLastTotal;
            private long mLastIdle;
    
            public CpuInfo() {
                mUsage = 0;
                mLastTotal = 0;
                mLastIdle = 0;  
            }
    
            private int  getUsage() {
                return mUsage;
            }
    
            public void update(String[] parts) {
                // the columns are:
                //
                //      0 "cpu": the string "cpu" that identifies the line
                //      1 user: normal processes executing in user mode
                //      2 nice: niced processes executing in user mode
                //      3 system: processes executing in kernel mode
                //      4 idle: twiddling thumbs
                //      5 iowait: waiting for I/O to complete
                //      6 irq: servicing interrupts
                //      7 softirq: servicing softirqs
                //
                long idle = Long.parseLong(parts[4], 10);
                long total = 0;
                boolean head = true;
                for (String part : parts) {
                    if (head) {
                        head = false;
                        continue;
                    }
                    total += Long.parseLong(part, 10);
                }
                long diffIdle   =   idle - mLastIdle;
                long diffTotal  =   total - mLastTotal;
                mUsage = (int)((float)(diffTotal - diffIdle) / diffTotal * 100);
                mLastTotal = total;
                mLastIdle = idle;
                Log.i(TAG, "CPU total=" + total + "; idle=" + idle + "; usage=" + mUsage);
            }
        }
    }
    

    【讨论】:

    • 我们不能在 android 8.0 中
    • 我们如何在 android 8 中获取 cpu 使用率
    【解决方案2】:

    你可以用这个得到每个核心的频率...

    try {
         double currentFreq;
         RandomAccessFile readerCurFreq;
         readerCurFreq = new RandomAccessFile("/sys/devices/system/cpu/cpu0/cpufreq/scaling_cur_freq", "r");
         String curfreg = readerCurFreq.readLine();
         currentFreq = Double.parseDouble(curfreg) / 1000;
         readerCurFreq.close();
         String finalfre = "Curent Frequency of Core 0 is" + currentFreq;
     } catch (IOException ex) {
         String finalfre = "Core is Idle";
        ex.printStackTrace();
     }
    

    通过核心数量循环。这样您就可以获得所有内核的频率。有时,如果内核空闲或停止,此代码可能会产生异常。处理它,你很高兴

    【讨论】:

    • 您知道如何将其转换为百分比吗?以 % 为单位获取每个核心的 CPU 使用率?
    • 这在 Android 8+ 设备上是不可能的。因为,对 /proc/stat 的访问受限于 API 26。stackoverflow.com/questions/52782894/…
    【解决方案3】:

    感谢 user1549150 的精彩回答。但不适用于我的情况。 我正在将您的 java 代码移植到本机,但是在 java 时它给出了错误的 difTotal 和 difIdle。

    对我来说,/proc/stat 如下所示,

    第一个

    * cpu  2626387 6180 852236 7911540 2469 121 3138 0 0 0
      cpu0 499189 2940 389423 1952572 589 84 2863 0 0 0
      cpu1 711524 1036 147360 1990743 670 11 132 0 0 0
      cpu2 703355 1085 156577 1989813 591 14 65 0 0 0
      cpu3 712318 1118 158875 1978412 618 11 78 0 0 0
      intr 58674412 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 ..
    

    第二次

    * cpu  2626622 6180 852296 7911655 2469 121 3138 0 0 0
      cpu0 499235 2940 389448 1952603 589 84 2863 0 0 0
      cpu1 711580 1036 147372 1990777 670 11 132 0 0 0
      cpu2 703416 1085 156589 1989842 591 14 65 0 0 0
      cpu3 712389 1118 158885 1978432 618 11 78 0 0 0
      intr 58679023 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 0 0 ...
    

    解析出来的 difftime 是

      CPU difTot[410] difIdle[115]
      CPU difTot[102] difIdle[31]
      CPU difTot[102] difIdle[34]
      CPU difTot[102] difIdle[29]
      CPU difTot[101] difIdle[20]
    

    下面给出了适当的核心使用时间。

      CORE[0] tot[11402481] idl[7911655] use[71]
      CORE[1] tot[2847762] idl[1952603] use[69]
      CORE[2] tot[2851578] idl[1990777] use[66]
      CORE[3] tot[2851602] idl[1989842] use[71]
      CORE[4] tot[2851531] idl[1978432] use[80]
    

    最终 toString 给出

      CPU Usage :Tot[71] Core0[69] Core1[66] Core2[71] Core3[80]
    

    我的设备是galaxy note2(rooted)

    这里是源代码。 希望有人能得到救赎。

    //GQPHD(bispro89@gmail.com)
    void printCpuState()
    {
    std::ifstream is("/proc/stat");
    std::stringstream buffer;
    buffer << is.rdbuf();
    std::string strbuff(buffer.str());
    
    LOGV("********** start /proc/stat log\n* %s\n********** end /proc/stat log",strbuff.c_str());
    std::vector<std::string> vec;
    vec = Tokenize(strbuff);
    
    //@ref http://stackoverflow.com/questions/11739444/how-to-get-usage-of-each-cpu-core-on-android
    int cntcpu = 0;
    for(int i = 0 ; i < vec.capacity(); i++){
        std::string str = vec[i];
        if( (str.find("cpu") != string::npos ) )  {//if contains str
    
            // the columns are:
            //
            //      0 "cpu": the string "cpu" that identifies the line
            //      1 user: normal processes executing in user mode
            //      2 nice: niced processes executing in user mode
            //      3 system: processes executing in kernel mode
            //      4 idle: twiddling thumbs
            //      5 iowait: waiting for I/O to complete
            //      6 irq: servicing interrupts
            //      7 softirq: servicing softirqs
            //
            long idle = atol(vec[i+4].c_str());//Long.parseLong(parts[4], 10);
            long total = 0;
            bool head = true;
            for(int j = 0 ; j < 7; j++){
                total += atol(vec[i+j+1].c_str());
            }
            long diffIdle   =   idle - mLastIdle[cntcpu];
            long diffTotal  =   total - mLastTotal[cntcpu];
            int usage = (int)((float)(diffTotal - diffIdle) / diffTotal * 100);
            mUsage[cntcpu] = usage;
            mLastTotal[cntcpu] = total;
            mLastIdle[cntcpu] = idle;
    
            LOGV("CPU difTot[%d] difIdle[%d]",diffTotal,diffIdle);
    
            cntcpu++;
        }
    
    }
    for(int i = 0 ; i < 5 ; i++){
        LOGV("CORE[%d] tot[%d] idl[%d] use[%d]",i,mLastTotal[i],mLastIdle[i],mUsage[i]);
    }
    
    LOGV("CPU Usage :Tot[%d\%] Core0[%d\%] Core1[%d\%] Core2[%d\%] Core3[%d\%]",
            mUsage[0],
            mUsage[1],
            mUsage[2],
            mUsage[3],
            mUsage[4]
    );
    is.close();
    }
    

    thnx user1549150

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      • 2012-07-04
      • 2014-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多