SwarmApps Code Blog

December 20, 2009

A quick way to get system resource usage info for your program in C++

Filed under: c++, General Code — Tags: , , , , , , , , — swarmapps @ 3:59 am

I’m working on a custom server for an app I’ve been writing.  I’ve already proven the concept and now I’m starting to get into serious, releasable code.  One open question I have is how many users can I expect a single instance of my server to handle.  To help me figure that out I’m instrumenting the heck out of my beta code and recording such things as polling loop time, data flow, and CPU usage.

Finding CPU usage from within a C++ program turned out to be one of the more obscure things to accomplish.  I did plenty of searching online and came up with many answers and even a few libraries that appear to give access to the data.  But, the libraries seemed overly large for what must be a simple task and the examples I found were incomplete.

In the end, I opted for using standard unix/linux commands.  From a command line, if you were to type “ps aux | grep MyAppName” you would get a line similar to this:

username   20657  99.6  0.0    75328    332 s000  R+   10:38PM   0:13.48 ./MyAppName

The first number after “username” is the CPU usage (99.6) of your program and the second number is the memory usage (0.0).  It seemed to me you should be able to use this formatted information pretty easily.

It turns out you can using a combination of system() command, command line piping and redirection, and file parsing.  It’s fast, simple, and effective..  Just what I was looking for.  The following code will get it done for you:

—-

#include <boost/algorithm/string.hpp>
#include <boost/regex.hpp>
#include <boost/algorithm/string/regex.hpp>

#include <time.h>
#include <stdlib.h>

#include <sstream>
#include <iostream>
#include <vector>
#include <string>

using namespace std;
using namespace boost;

int main (int argc, char * const argv[]) {
	// First get my process ID
	int myProcID = getpid();

	// Now we use system commands to find our process id and store the result in a standard text file
	// The "grep -v grep" command filters out the system command itself from the process search.
	stringstream theCommand;
	theCommand << "ps aux | grep " << myProcID << " | grep -v grep > result.txt";
	 time_t lastCheck = time(NULL);
         while (1) {
 		time_t now = time(NULL);
 		 // Only print every 5 seconds or so to prevent overwhelming the output
 		if ((now - lastCheck) >= 4) {
			// The clock code is here to show how efficient this method can be.
			clock_t start = clock();

			// Run the command
			system(theCommand.str().c_str());

			// now open the text file and read the result line
			ifstream infile;
			infile.open("result.txt");
			string aLine;
			getline(infile, aLine);

			// print the line just so you can see it.
			cout << aLine << "\n";

			// set up a receiver for the boost split function
			vector<string> processParameters;
			// Split the recieved line on the " " seperator.  There are multiple spaces between parameters, so use token_compress_on
			split( processParameters, aLine, is_any_of(" "), token_compress_on );

			// Output the results
			cout << "My CPU usage is " << processParameters[2] << ", and mem usage is " << processParameters[3] << "\n";

			// Close the file (you might want to delete it too.)
			infile.close();

			// reset my time check
			lastCheck = now;

			// show how quick this is.  On my machine it's ~ 650 clock cycles (at 1.83 GHz, thats approx 3 10-millionths of a second)
			cout << "CPU check took " << (clock() - start) << " cycles to complete\n";

		}
	}
        return 0;

}

I’ve used the boost library here to simplify the parsing of the text line.  You don’t need to do that if you don’t want to, but I assure you you’ll find using boost easier than spinning your own text parsing code.

Happy coding!

Mike

Advertisement

Leave a Comment »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: WordPress Classic. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.