如何监控windows进程的句柄、内存和cpu(二)

2023-10-27

接下来,我们看如何获取进程的CPU使用率:

CPU使用率:指进程在一段时间内消耗的CPU时间与该时间段长度的比值。

windows本身并没有提供直接获取进程CPU使用率的函数,但我们可以根据进程的计时信息来间接计算出进程的瞬时CPU占用:

1)记录进程当前在用户模式和内核模式下已经执行的时间;

2)1s后,再次记录进程在用户模式和内核模式下已经执行的时间;

3)将两次时间相减,就是这1s时间内进程在CPU上执行的时间;用执行时间/记录间隔时间 = 进程的CPU占比

 

老规矩,看需要用到哪些系统API函数:

GetProcessTimes函数:

BOOL GetProcessTimes(
    HANDLE hProcess,
    LPFILETIME lpCreationTime,
    LPFILETIME lpExitTime,
    LPFILETIME lpKernelTime,
    LPFILETIME lpUserTime
);

 

函数功能:获取指定进程的计时信息

参数:

hProcess:指定进程的句柄;

lpCreationTime:返回进程的创建时间;

lpExitTime:返回进程的退出时间,若进程尚未退出,此返回值内容不确定;

lpKernelTime:返回进程在内核模式下已执行的时间;

lpUserTime:返回进程在用户模式下已执行的时间;

返回值:函数成功返回非0,失败返回0.

详见:https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getprocesstimes

需要注意的是,内核模式下和用户模式下的执行时间,是指进程的所有线程的执行时间和,如果改进程在多个CPU核上运行,则值可能会超过经过的实时时间。这点也比较好理解,如果进程支持在多核上运行,每个核上的执行时间相加,则有可能大于实时经过的时间。

 

GetSystemTimeAsFileTime函数:

void GetSystemTimeAsFileTime(
  LPFILETIME lpSystemTimeAsFileTime
);

 

函数功能:检索当前系统日期和时间,这个函数返回的时间精度相对于其他的API函数高很多,以ns为单位

参数:lpSystemTimeAsFileTime:返回当前系统日期和时间

详见:https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemtimeasfiletime

 

GetSystemInfo函数

void GetSystemInfo(
  LPSYSTEM_INFO lpSystemInfo
);

 

函数说明:检索当前系统的信息

参数:lpSystemInfo返回系统的信息

SYSTEM_INFO结构:https://docs.microsoft.com/zh-cn/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info

 

实现代码如下:

//时间转换
uint64_t get_utc_time(const FILETIME* ftime)
{
    LARGE_INTEGER ti;
    ti.LowPart = ftime->dwLowDateTime;
    ti.HighPart = ftime->dwHighDateTime;
    return ti.QuadPart;
}

//获取CPU核数
int get_processor_number()
{
    SYSTEM_INFO info;
    GetSystemInfo(&info);
    return (int)info.dwNumberOfProcessors;
}

//获取CPU使用率
float get_cpu_usage(HANDLE hProcess, int processor)
{
    FILETIME now;
    FILETIME creation_time;
    FILETIME exit_time;
    FILETIME kernel_time;
    FILETIME user_time;
    int64_t system_time;
    int64_t time;
    int64_t system_time_delta;
    int64_t time_delta;  
    DWORD exitcode;

    int64_t last_time;
    int64_t last_system_time;
    float cpu;

    GetSystemTimeAsFileTime(&now); //获取当前时间(高精度)
    //判断进程是否已经退出
    GetExitCodeProcess(hProcess, &exitcode);
    if (exitcode != STILL_ACTIVE) {
        printf("process had exit.\n");
        return -1;
    }  

    //计算占用CPU的百分比
    if (!GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time, &user_time))
    {
        printf("GetProcessTimes faild.\n");
        return -1;
    }

    system_time = (get_utc_time(&kernel_time) + get_utc_time(&user_time))/ processor;
    time = get_utc_time(&now);  
    last_system_time = system_time;
    last_time = time;

    //第二次
    Sleep(1000);
    //计算占用CPU的百分比
    GetSystemTimeAsFileTime(&now);//获取当前时间(高精度)
    if (!GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time, &user_time))
    {
        printf("GetProcessTimes faild.\n");
        return -1;
    }

    system_time = (get_utc_time(&kernel_time) + get_utc_time(&user_time))/ processor;
    time = get_utc_time(&now);

    system_time_delta = system_time - last_system_time;
    time_delta = time - last_time;  

    cpu = (float)system_time_delta * 100 / (float)time_delta;
    return cpu;
}


float getProcessCPUUsage(LPCWSTR processName)
{
    int processor;
    float cpuUsage;
    float processCpuUsageAll=0;
    std::vector<HANDLE> processHandleGroup = GetProcessHandle(processName);
    printf("vector size is %d.\n",processHandleGroup.size());
    if(0 == processHandleGroup.size())
    {
        return -2;
    }

    processor = get_processor_number();
    printf("processor is %d.\n",processor);
    std::vector<HANDLE>::iterator it;
    for(it=processHandleGroup.begin();it!=processHandleGroup.end();it++)
    {
        cpuUsage = get_cpu_usage(*it,processor);
        CloseHandle(*it);
        if(cpuUsage < 0)
        {
            continue;
        }

        processCpuUsageAll += cpuUsage;
        printf("Current Process cpu : %f \n",cpuUsage);
    }
    printf("Process cpu usage sum: %f \n",processCpuUsageAll);
    return processCpuUsageAll;
}

结合上一篇获取的进程句柄,我们就能很方便的获取所有指定进程名的进程当前CPU占用情况。

下一篇将介绍如何使用进程句柄获取进程当前句柄数和内存占用

本文为作者原创,如需转载,请在评论区征得作者同意,原创链接:https://blog.csdn.net/anranjingsi/article/details/106124258

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何监控windows进程的句柄、内存和cpu(二) 的相关文章

随机推荐

  • 大牛用十年功力带你彻底理解JVM垃圾回收器:ZGC,回收设计

    回收设计 ZGC的并发回收算法采用的也是 目的空间不变性 的设计 关于目的空间不变性的更多内容可以参考第7章 在第7章中提到 Shenandoah从JDK 13开始也采用 目的空间不变性 的设计 但是ZGC与Shenandoah相比 还是有
  • 前端页面多字段模糊查询

    前端页面多字段模糊查询 本文主要参考了大佬们的内容 整合记录一下具体内容 1 实现代码 arr是前端原有的列表数组 后台返回来的数据 var arr id 1 aa asd bb 阿斯顿 cc 123 id 2 aa Awr bb 艾沃瑞
  • 云原生 AI 工程化实践之 FasterTransformer 加速 LLM 推理

    01 背景 OpenAI 在 3 月 15 日发布了备受瞩目的 GPT4 它在司法考试和程序编程领域的惊人表现让大家对大语言模型的热情达到了顶点 人们纷纷议论我们是否已经跨入通用人工智能的时代 与此同时 基于大语言模型的应用也如雨后春笋般出
  • Java-String的用法

    Java String的用法 文章目录 Java String的用法 1 介绍 2 实例化String的两种方法 3 String内容的比较 3 1使用 进行基本数据类型的比较 3 2String中使用 比较字符串的内容 3 3使用equa
  • SpringCloud中ribbon的配置文件和属性配置原理

    https blog csdn net hry2015 article details 78357990 作者写的非常详细
  • Mac下使用命令行 mvn 给Maven打包

    使用命令行 mvn 给Maven打包 sudo mvn clean install Dmaven test skip true Dmaven javadoc skip true Dmaven test skip true 跳过单元测试 Dm
  • wms仓储信息化的应用和发展趋势

    随着在线零售市场日益成熟 电子商务不断蓬勃发展 电商仓储需求也呈现高速增长的态势 仓储业也进入到了质的变化阶段 wms仓储信息化的应用和发展趋势 在电商供应链中 企业尤为关心的 是如何把货物更快更准确地送到客户手中 以及如何应对随时变化的订
  • 畅购中

    项目第七天 ES类型 要答出 type版本前和版本后的改变 ES查询方法 使用ElasticsearchRestTemplate对象来构建 ES的默认规则 ES能够自动存储未提交创建字段信息的数据 目的 未指定时ES为了可以更好的支持聚合和
  • python列表索引超出范围怎么解决_Python的列表怎么用?你会吗?Python每日学习打卡...

    Python的列表怎么用 你会用吗 本文主要介绍了Python中列表 List 的详解操作方法 包含创建 访问 更新 删除 其它操作等 需要的朋友可以参考下 Python列表 1 创建列表 只要把逗号分隔的不同的数据项使用方括号括起来即可
  • MFC CListctrl里面使用编辑框和下拉框

    对于需要使用到子控件的单元格 就把子控件移动到需要使用的位置就好 1 创建工程 添加控件CEdit和CListCtrl到对话框 分别添加控件变量 protected CEdit m Edit CListCtrl m ListCtrl int
  • 分布式注册中心 Eureka 与 zookeeper 的区别、原理及各自优缺点

    前言 在微服务的开发过程中 如果使用的是 Dubbo 那就必须使用到 Zookeeper 在使用 Spring Cloud Eureka 时 自然其功能更强大得多 博主也不得不感叹 Spring Cloud Eureka 后来者居上呀 Du
  • vue3 使用 vue.config.js 配置使用scss全局变量

    vue3 使用 vue config js 配置使用scss全局变量 记录学习和开发中遇到的问题或难题 刚开始我在网上查找了许多资料 都是需要什么安装安装 sass resources loader 和配置什么乱七八糟的 我没有尝试过 因为
  • 【社区图书馆】《实战大数据—— 分布式大数据分析处理系统开发与应用》书评

    实战大数据 分布式大数据分析处理系统开发与应用 从大数据技术基础概念出发 介绍了大数据分析的流程和大数据分析处理系统的组成 以及大数据集群的搭建 并在此基础上讲解了多种不同技术构成的离线 实时数据分析系统实战项目 全书共10章 包括大数据概
  • Vue.js 项目查看 vue版本号

    vue V或者是vue version查询的是vue cli的版本 也就是vue脚手架的版本 如果想要查看vue的版本 直接去项目中 在根目录下 找到package json文件夹 找 dependencies 然后就可以看到你装的vue的
  • day2作业

    作业说明 请在下方提示位置 补充代码 完成 青春有你2 选手图片爬取 将爬取图片进行保存 保证代码正常运行 打印爬取的所有图片的绝对路径 以及爬取的图片总数 此部分已经给出代码 请在提交前 一定要保证有打印结果 如下图所示 深度学习一般过程
  • nvm包管理工具下载安装

    1 去github官网 输入nvm windows 点击第一个nvm项目 在右侧点击releases 选择箭头指向的安装包 2 下载很快 但是安装前 得先卸载本机的nodejs 并且为nvm的包创建一个英文文件夹 这里我在D盘创建了一个no
  • JAVA遇见HTML—JSP篇—Mac系统(一.JAVA WEB)

    1 什么是Web应用程序 Web应用程序是一种可以通过Web访问的应用程序 Web应用程序的最大好处是用户很容易访问应用程序 用户只需要有浏览器即可 不需要再安装其他软件 为什么要学习Web应用程序 我们说Web应用程序开发 是目前软件开发
  • CC00202.CloudKubernetes——

    一 NoSchedule静止调度 容器强制驱逐 为master01打一个污点 NoSchedule类型 静止调度 容器会被强制驱逐 为master01节点打入污点 NoExecute类型 root k8s master01 kubectl
  • vscode统计项目代码行数插件——vecode counter

    vscode统计项目代码行数插件 vscode counter vscode counter 安装插件 使用方式 插件缺点 仅针对go来说的 vscode counter 安装插件 按照途中的地方进行搜索就能找到该插件的入口 点击insta
  • 如何监控windows进程的句柄、内存和cpu(二)

    接下来 我们看如何获取进程的CPU使用率 CPU使用率 指进程在一段时间内消耗的CPU时间与该时间段长度的比值 windows本身并没有提供直接获取进程CPU使用率的函数 但我们可以根据进程的计时信息来间接计算出进程的瞬时CPU占用 1 记