linux c++获取进程的实时内存使用和cpu占用

看起来很简单的问题,本来想在网上找一个,找了一圈没有一个简洁合适的,遂自己写一个,部分代码copy自网帖并稍加改造。

头文件:

#ifndef _UTILITY_RESOURCE_0EFC332C_91AC_4126_9BAB_F32C12AAD376_H__
#define _UTILITY_RESOURCE_0EFC332C_91AC_4126_9BAB_F32C12AAD376_H__

#include <map>
#include <tuple>

class UtilityResource
{
public:
	static int cpu_count();
	// 当前cpu,区分子线程
	static void current_cpu(std::map<int, double>& cpus);

	static uint64_t total_mem();
	// 当前内存,RES
	static uint64_t current_mem();

private:
	static void _enmu_pid_sysfile();
	static std::string _read_stat_file(const char* file_name);
	static int _get_process_time_all();
	static int _get_process_time_tid(int tid);
	static uint64_t _get_res_mem_all();
	static uint64_t _get_res_mem_pid();

private:
	static int g_cpu_count;
	static int g_pid;
	static std::map<int, std::tuple<uint64_t, uint64_t, uint64_t, uint64_t>> g_tid_cpus; // <tid: <last, curr, last_all, curr_all>>
};

#endif // _UTILITY_RESOURCE_0EFC332C_91AC_4126_9BAB_F32C12AAD376_H__

源文件:

#include "utility_resource.h"

#include <sys/types.h>
#include <sys/sysinfo.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <dirent.h>
#include <string>

int UtilityResource::g_cpu_count = sysconf(_SC_NPROCESSORS_CONF);
int UtilityResource::g_pid = getpid();
std::map<int, std::tuple<uint64_t, uint64_t, uint64_t, uint64_t>> UtilityResource::g_tid_cpus;

int UtilityResource::cpu_count()
{
	return g_cpu_count;
}

void UtilityResource::current_cpu(std::map<int, double>& cpus)
{
	_enmu_pid_sysfile();
	if (cpus.empty())
	{
		for (auto it = g_tid_cpus.begin(); it != g_tid_cpus.end(); ++it)
		{
			cpus[it->first] = 0.0f;
		}
	}
	for (auto it = cpus.begin(); it != cpus.end(); ++it)
	{
		auto itf = g_tid_cpus.find(it->first);
		if (itf != g_tid_cpus.end())
		{
			std::get<0>(itf->second) = std::get<1>(itf->second);
			std::get<1>(itf->second) = _get_process_time_tid(it->first);
			std::get<2>(itf->second) = std::get<3>(itf->second);
			std::get<3>(itf->second) = _get_process_time_all();
			it->second = double(std::get<1>(itf->second) - std::get<0>(itf->second)) / (std::get<3>(itf->second) - std::get<2>(itf->second)) * g_cpu_count * 100;
		}
		else
		{
			it->second = 0.0f;
		}
	}
}

uint64_t UtilityResource::total_mem()
{
	return _get_res_mem_all();
}

uint64_t UtilityResource::current_mem()
{
	return _get_res_mem_pid();
}

void UtilityResource::_enmu_pid_sysfile()
{
	auto last_tid_cpus = g_tid_cpus;
	g_tid_cpus.clear();
	DIR* dir = opendir("/proc/self/task");
	if (dir == NULL)
	{
		return;
	}
	struct dirent* entry;
	while ((entry = readdir(dir)))
	{
		if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
		{
			continue;
		}
		int tid = std::atoi(entry->d_name);
		auto it = last_tid_cpus.find(tid);
		if (it != last_tid_cpus.end())
		{
			g_tid_cpus[tid] = it->second;
		}
		else
		{
			g_tid_cpus[tid] = std::forward_as_tuple(0, 0, 0, 0);
		}
	}
	closedir(dir);
}

std::string UtilityResource::_read_stat_file(const char* file_name)
{
	std::string stat_info;
	FILE* fd;
	if ((fd = fopen(file_name, "r")))
	{
		stat_info.resize(1024);
		fgets(const_cast<char*>(stat_info.c_str()), 1024, fd);
		stat_info.resize(strlen(stat_info.c_str()));
		fclose(fd);
	}
	return stat_info;
}

int UtilityResource::_get_process_time_all()
{
	std::string all_sysinfo = _read_stat_file("/proc/stat");

	char tcpu[7];
	unsigned int user, nice, sys, idle, iowait, irq, softirq, steal;
	sscanf(all_sysinfo.c_str(), "%s%d%d%d%d%d%d%d%d", tcpu, &user, &nice, &sys, &idle, &iowait, &irq, &softirq, &steal);
	return user + nice + sys + idle + iowait + irq + softirq + steal;
}

int UtilityResource::_get_process_time_tid(int tid)
{
	std::string tid_syspath = "/proc/self/task/";
	tid_syspath += std::to_string(tid) + "/stat";

	std::string tid_sysinfo = _read_stat_file(tid_syspath.c_str());

	const char *b = tid_sysinfo.c_str();
	const char *e = b + tid_sysinfo.size();
	for (int i = 0; i < 13 && b++ < e;)
	{
		while (*(b++) != ' ');
		++i;
	}
	int utime, stime, cutime, cstime;
	sscanf(b, "%d%d%d%d", &utime, &stime, &cutime, &cstime);
	return utime + stime + cutime + cstime;
}

uint64_t UtilityResource::_get_res_mem_all()
{
	struct sysinfo s;
	if(0 == sysinfo(&s))
	{
		return s.totalram * s.mem_unit;
	}
	return 0;
}

uint64_t  UtilityResource::_get_res_mem_pid()
{
	std::string pid_meminfo = _read_stat_file("/proc/self/statm");
	uint64_t virt, res;
	sscanf(pid_meminfo.c_str(), "%lu%lu", &virt, &res);
	return res * (getpagesize() / 1024);
}

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值