Total CPU usage for Linux

May 2, 2012 at 11:06am
I'm looking for a way, to get the total CPU usage from C++. Similar to what a task manager would show.

I found a program which does that in Windows: http://en.literateprograms.org/CPU_usage_using_performance_counters_%28C,_Windows_2000%29

Is there an equivalent for Linux?
May 2, 2012 at 3:22pm
Read the first four values from /proc/stat, which are the user, nice, system and idle times, in that order. The CPU usage is UNS/(UNS+Idle).
May 2, 2012 at 8:54pm
I've arrived at a similar solution, but your solution, as far as I can see, will give the avarage load since the computer started.

Now I'm reading /proc/stat twice with a small interval inbetween, and measure the difference between the two. This is the actuall CPU load (hopefully). I'll try to post a working soltuion for future use when I finish it.
May 2, 2012 at 9:12pm
Yes, of course. CPU usage can be measured only over a period of time (or when you don't, there are only two possible values: idle and busy).
May 3, 2012 at 12:38pm
Here is the code I came up with.
Sometimes it gives values slightly negative. I think this can be accounted for the inaccuracy of the time measurement, or the /proc/stat file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#include <unistd.h>

#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
#include <boost/date_time.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>


//This function reads /proc/stat and returns the idle value for each cpu in a vector
std::vector<long long> get_idle() {

	//Virtual file, created by the Linux kernel on demand
	std::ifstream in( "/proc/stat" );

	std::vector<long long> result;

	//This might broke if there are not 8 columns in /proc/stat
	boost::regex reg("cpu(\\d+) (\\d+) (\\d+) (\\d+) (\\d+) (\\d+) (\\d+) (\\d+) (\\d+)");

	std::string line;
	while ( std::getline(in, line) ) {

		boost::smatch match;
		if ( boost::regex_match( line, match, reg ) ) {

			long long idle_time = boost::lexical_cast<long long>(match[5]);

			result.push_back( idle_time );
		}


	}
	return result;
}

//This function returns the avarege load in the next interval_seconds for each cpu in a vector
//get_load() halts this thread for interval_seconds
std::vector<float> get_load(unsigned interval_seconds) {

	boost::posix_time::ptime current_time_1 = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time();
	std::vector<long long> idle_time_1 = get_idle();

	sleep(interval_seconds);

	boost::posix_time::ptime current_time_2 = boost::date_time::microsec_clock<boost::posix_time::ptime>::universal_time();
	std::vector<long long> idle_time_2 = get_idle();

	//We have to measure the time, beacuse sleep is not accurate
	const float total_seconds_elpased = float((current_time_2 - current_time_1).total_milliseconds()) / 1000.f;
	
	std::vector<float> cpu_loads;

	for ( unsigned i = 0; i < idle_time_1.size(); ++i ) {

		//This might get slightly negative, because our time measurment is not accurate
		const float load = 1.f - float(idle_time_2[i] - idle_time_1[i])/(100.f * total_seconds_elpased);
		cpu_loads.push_back( load );

	}
	return cpu_loads;
}

int main() {

	const unsigned measurement_count = 5;
	const unsigned interval_seconds = 5;

	for ( unsigned i = 0; i < measurement_count; ++i ) {

		std::vector<float> cpu_loads = get_load(interval_seconds);
		for ( unsigned i = 0; i < cpu_loads.size(); ++i ) {
			std::cout << "cpu " << i << " : " << cpu_loads[i] * 100.f << "%" << std::endl;
		}
	}


	return 0;
}
Last edited on May 3, 2012 at 12:39pm
May 3, 2012 at 2:03pm
Hmmm....never thought much about CPU usage until you made this thread. Don't think any of my code taxes the CPU that bad though. I'll have to bookmark this for later reference :).
Topic archived. No new replies allowed.