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