How to get usage of each cpu core on android

2020-03-07 06:40发布

I develop a widget on Android which display many useful informations.

I am trying to modify this method to return the percent of use of one cpu core, in order to have the percent of use of each core !!!

On my HTC One X, i have in " /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

I use this method to return the percent of use of all cpu core.

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;
} 

I am trying this to get cpu1's use, but it's don't work:

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;
}

This allows to read one line and the cursor stay at the end of the line:

String load = reader.readLine();

So, i tried to use it twice in order to get CPU0's use and third to get CPU1. But the result is always 0 or 100 ... I don't understand !

Am i using the right way? Am i using the right file? Is this result normal?

Please HELP !!!

3条回答
来,给爷笑一个
2楼-- · 2020-03-07 07:19

You can get the frequency of each core with this...

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();
 }

loop this through the number of cores. So that you can get the frequency for all the cores. Some times if the core is idle or stopped, this code may produce a exception. handle it and you're good to go

查看更多
叛逆
3楼-- · 2020-03-07 07:21

thanks for nice answer of user1549150. but not works in my case. i was porting your java code into native, but it gives wrong difTotal and difIdle when java.

for me, /proc/stat as shown here,

1st

* 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 ..

2nd

* 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 ...

and parsed diftime is

  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]

which gives proper core usage time below.

  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]

final toString gives

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

my devies is galaxy note2(rooted)

here is source code. hope may someone will given salvation.

//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

查看更多
虎瘦雄心在
4楼-- · 2020-03-07 07:33
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);
        }
    }
}
查看更多
登录 后发表回答