我在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 ......我不明白!
我使用正确的方法吗? 我使用的是正确的文件吗? 这个结果是否正常?
请帮助!!!
答案 0 :(得分:6)
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);
}
}
}
答案 1 :(得分:2)
您可以通过此获取每个内核的频率...
//Here is one way to tackle the problem:-
#include <stdio.h>
int check(int* a,int* b,int n){
int i=0;
for(i=0;i<n;i++){
if(!(a[i]==b[i]))
{
return 0;
}
}
return 1;
}
int main()
{
int a[4]={1,2,3,5};
int b[4]={1,2,3,4};
printf("%d",check(a,b,4));
return 0;
}
通过内核数循环。这样您就可以获得所有内核的频率。有时,如果内核处于空闲或停止状态,则此代码可能会产生异常。处理好,您就可以走了
答案 2 :(得分:0)
感谢user1549150的好评。但在我的情况下不起作用。 我正在将你的java代码移植到native中,但是在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 ...
并解析了diftime是
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]
final toString给出
CPU Usage :Tot[71] Core0[69] Core1[66] Core2[71] Core3[80]
我的devies是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