I am trying to pass a file to a function. The file is /proc/stat, and the CPU portion works fine. This is just a small part of another file, broken down for help. It is run every second, and I'd prefer not to open/close the file every second, hence opening it once and passing to the function.
The issue is that when the file is passed to the function, it only grabs the info once and displays the correct CPU. It gives no result thereafter. If the file is opened within the function, it works fine.
cpu.cpp:
Code:
/*
g++ -std=c++17 -Ofast -Wall cpu.cpp -o cpu -lpthread -lX11
*/
#include <sstream>
#include<fstream>
#include<iostream>
#include<string>
#include<chrono>
#include<thread>
#include"sys/sysinfo.h"
#include<sys/types.h>
#include<ctime>
#include<sys/ioctl.h>
#include<sys/socket.h> /* socket() */
#include<arpa/inet.h>
#include<cstdlib>
#include<cstdio>
#include<unistd.h> /* close() */
#include<linux/if.h> /* struct ifreq */
#include<cstring>
#include<X11/Xlib.h>
using namespace std;
std::string cpuPercent(FILE *file)
{
static unsigned int lastTotalUser, lastTotalUserLow, lastTotalSys, lastTotalIdle;
float percent;
short intPercent;
std::string s;
//rewind(file);
fseek(file, 0L, SEEK_SET);
if (fseek(file, 0L, SEEK_SET) != 0 )
std::cout << "Didn't reset properly!" << std::endl;
unsigned long long totalUser, totalUserLow, totalSys, totalIdle, total;
fscanf(file, "cpu %llu %llu %llu %llu", &totalUser, &totalUserLow, &totalSys, &totalIdle);
if (totalUser < lastTotalUser || totalUserLow < lastTotalUserLow ||
totalSys < lastTotalSys || totalIdle < lastTotalIdle)
{
//Overflow detection. Just skip this value.
percent = -1.0;
}else{
total = (totalUser - lastTotalUser) + (totalUserLow - lastTotalUserLow) + (totalSys - lastTotalSys);
percent = total * 100;
total += (totalIdle - lastTotalIdle);
percent /= total;
}
lastTotalUser = totalUser;
lastTotalUserLow = totalUserLow;
lastTotalSys = totalSys;
lastTotalIdle = totalIdle;
intPercent = percent;
s = to_string(intPercent);
return s + "% ";
}
std::string cpuPercent2()
{
FILE* file2 = fopen("/proc/stat", "r");
static unsigned int lastTotalUser2, lastTotalUserLow2, lastTotalSys2, lastTotalIdle2;
float percent;
short intPercent;
std::string s;
rewind(file2);
fseek(file2, 0L, SEEK_SET);
if (fseek(file2, 0L, SEEK_SET) != 0 ) {
std::cout << "Didn't reset properly!" << std::endl;
}
unsigned long long totalUser, totalUserLow, totalSys, totalIdle, total;
fscanf(file2, "cpu %llu %llu %llu %llu", &totalUser, &totalUserLow, &totalSys, &totalIdle);
if (totalUser < lastTotalUser2 || totalUserLow < lastTotalUserLow2 ||
totalSys < lastTotalSys2 || totalIdle < lastTotalIdle2)
{
//Overflow detection. Just skip this value.
percent = -1.0;
}else{
total = (totalUser - lastTotalUser2) + (totalUserLow - lastTotalUserLow2) + (totalSys - lastTotalSys2);
percent = total * 100;
total += (totalIdle - lastTotalIdle2);
percent /= total;
}
lastTotalUser2 = totalUser;
lastTotalUserLow2 = totalUserLow;
lastTotalSys2 = totalSys;
lastTotalIdle2 = totalIdle;
intPercent = percent;
s = to_string(intPercent);
fclose(file2);
return s + "% ";
}
int main(int argc, char* argv[])
{
FILE* file = fopen("/proc/stat", "r");
while(1)
{
std::cout << "Cpu (file passed to func): " << cpuPercent(file) << std::endl;
std::cout << "Cpu (file within func): " << cpuPercent2() << std::endl;
sleep(1);
}
fclose(file);
return 0;
}
Here is a side-by-side of the results printed out:
Code:
Cpu (file passed to func): 4% Cpu (file within func): 4%
Cpu (file passed to func): 0%
Cpu (file within func): 11%
Cpu (file passed to func): 0%
Cpu (file within func): 15%
Cpu (file passed to func): 0%
Cpu (file within func): 17%
Cpu (file passed to func): 0%
The file that is passed to the function only gives the first result. I suspect that it is either not reading /proc/stat properly or it is not resetting. The second file works fine.
Any ideas?