unordered_map<int, size_t> determined; // Init using the root process for (auto& pi : process_infos) { if (pi.pid == root_pid) { determined.insert({root_pid, pi.memory}); break; } } if (determined.empty()) returnfalse;
// Collect all childs process while (true) { auto iter = process_infos.begin(); int old_size = process_infos.size(); while (iter != process_infos.end()) { //cout<<"skip pid: "<<iter->pid<<endl; //cout<<"determined size: "<<determined.size()<<endl; if (determined.count(iter->ppid) != 0) { determined[iter->pid] = iter->memory; //cout<<"add pid: "<<iter->pid<<" memory: "<<iter->memory<<endl; process_infos.erase(iter); break; } iter++; } int new_size = process_infos.size(); if (old_size == new_size) break; } for (auto& [_, m] : determined) total_memory += m;
returntrue; }
intexec_shell(constchar* cmd, std::string & res) { FILE* pp = popen(cmd, "r"); // make pipe if (!pp) { return-1; } char tmp[1024]; // store the stdout per line while (fgets(tmp, sizeof(tmp), pp) != NULL) { if (tmp[strlen(tmp) - 1] == '\n') { tmp[strlen(tmp) - 1] = '\0'; } res += tmp; }
// close pipe, the return code is cmd's status // returns the exit status of the terminating command processor // -1 if an error occurs int rtn = pclose(pp); #ifndef _WIN32 rtn = WEXITSTATUS(rtn); #endif
return rtn; }
pair<int, size_t> physical_memory_used_by_process(int pid) { pair<int, size_t> result(-1, 0); #ifndef _WIN32 string file_name = "/proc/"+to_string(pid)+"/status"; FILE* file = fopen(file_name.c_str(), "r"); if (!file) return result; char line[128]; while (fgets(line, 128, file) != nullptr) { if (strncmp(line, "VmRSS:", 6) == 0) { int len = strlen(line);
constchar* p = line; for (; std::isdigit(*p) == false; ++p) { }
line[len - 3] = 0; result.second = atoi(p); } elseif (strncmp(line, "PPid:", 5) == 0) { int len = strlen(line);
constchar* p = line; for (; std::isdigit(*p) == false; ++p) { }