首页 > 系统相关 >C++ 获取特定进程的CPU使用率

C++ 获取特定进程的CPU使用率

时间:2022-12-23 16:59:21浏览次数:46  
标签:last cpu system C++ CPUusage time 使用率 CPU

近来发现笔记本在关闭屏幕后风扇转得特别快,打开屏幕后看任务管理器,风扇马上减速,也没有发现大量占用CPU的进程。于是想写一个小程序在后台记录每个进程的CPU使用情况,揪出锁屏后占用CPU的进程。于是自己写了一个C++类CPUusage,方便地监视不同进程的CPU占用情况。本人编程还只是个新手,如有问题请多多指教( •̀ ω •́ )!

计算原理为调用GetProcessTimes(),与上次调用得到的结果相减得到CPU占用时间,再除以两次调用的时间差,从而得到占用百分比。其中OpenProcess需要的权限为PROCESS_QUERY_LIMITED_INFORMATION,因此没有管理员权限也可以使用。

使用方法:

初始化: 可以在构造函数中指定pid,也可以用setpid()指定pid。   查看CPU占用情况: setpid()函数:     指定一个需要监视的进程的PID。 get_cpu_usage()函数:     查看CPU占用情况。打开进程失败,或者查看CPU占用情况失败,以及被监视的进程退出后,都会返回-1。每次使用setpid()指定新的pid后首次调用都会返回-2。指定PID后从第二次调用开始,会返回一个0~100的float,为此次调用与上一次调用这段时间内的CPU平均占用率。

代码:

CPUusage类:(CPUusage.h) 复制代码
#include <Windows.h>   
//原理:调用GetProcessTimes(),并与上次调用得到的结果相减,即得到某段时间内CPU的使用时间  
//C++ 获取特定进程规定CPU使用率  原文:http://blog.csdn.net/liuqx97bb/article/details/52058657  
class CPUusage {   
private:  
   typedef long long          int64_t;  
   typedef unsigned long long uint64_t;  
    HANDLE _hProcess;    
    int _processor;    //cpu数量    
    int64_t _last_time;         //上一次的时间    
    int64_t _last_system_time;    
  
  
    // 时间转换    
    uint64_t file_time_2_utc(const FILETIME* ftime);  
  
    // 获得CPU的核数    
    int get_processor_number();  
  
    //初始化  
    void init()  
    {  
        _last_system_time = 0;  
        _last_time = 0;  
        _hProcess = 0;  
    }  
  
    //关闭进程句柄  
    void clear()  
    {  
        if (_hProcess) {  
            CloseHandle(_hProcess);  
            _hProcess = 0;  
        }  
    }  
  
public:  
    CPUusage(DWORD ProcessID) {   
        init();   
        _processor = get_processor_number();  
        setpid(ProcessID);  
    }  
    CPUusage() { init(); _processor = get_processor_number(); }  
    ~CPUusage() { clear(); }  
  
    //返回值为进程句柄,可判断OpenProcess是否成功  
    HANDLE setpid(DWORD ProcessID) {   
        clear();    //如果之前监视过另一个进程,就先关闭它的句柄  
        init();   
        return _hProcess= OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, ProcessID);   
    }  
  
    //-1 即为失败或进程已退出; 如果成功,首次调用会返回-2(中途用setpid更改了PID后首次调用也会返回-2)  
   float get_cpu_usage();    
};  
复制代码

实现:(CPUusage.cpp)

复制代码
float CPUusage::get_cpu_usage()  
{  
  
    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;  
  
    float cpu = -1;  
  
    if (!_hProcess) return -1;  
  
    GetSystemTimeAsFileTime(&now);  
  
    //判断进程是否已经退出  
    GetExitCodeProcess(_hProcess, &exitcode);    
    if (exitcode != STILL_ACTIVE) {  
        clear();  
        return -1;  
    }  
  
    //计算占用CPU的百分比  
    if (!GetProcessTimes(_hProcess, &creation_time, &exit_time, &kernel_time, &user_time))  
    {  
        clear();  
        return -1;  
    }  
    system_time = (file_time_2_utc(&kernel_time) + file_time_2_utc(&user_time))  
        / _processor;  
    time = file_time_2_utc(&now);  
  
    //判断是否为首次计算  
    if ((_last_system_time == 0) || (_last_time == 0))  
    {  
        _last_system_time = system_time;  
        _last_time = time;  
        return -2;  
    }  
  
    system_time_delta = system_time - _last_system_time;  
    time_delta = time - _last_time;  
  
    if (time_delta == 0) {  
        return -1;  
    }  
  
    cpu = (float)system_time_delta * 100 / (float)time_delta;  
    _last_system_time = system_time;  
    _last_time = time;  
    return cpu;  
}  
  
CPUusage::uint64_t CPUusage::file_time_2_utc(const FILETIME* ftime)  
{  
    LARGE_INTEGER li;  
  
    li.LowPart = ftime->dwLowDateTime;  
    li.HighPart = ftime->dwHighDateTime;  
    return li.QuadPart;  
}  
  
int CPUusage::get_processor_number()  
{  
    SYSTEM_INFO info;  
    GetSystemInfo(&info);  
    return info.dwNumberOfProcessors;  
}  
复制代码

测试代码:

复制代码
#include "CPUusage.h"  
int _tmain(int argc, _TCHAR* argv[])  
{  
  
    CPUusage usg(12316);  
    for (int i = 0; i < 10; i++)  
    {  
        float cpu = usg.get_cpu_usage();  
        printf("Taskmgr.exe: %.2f%%\n", cpu);  
        Sleep(500);  
    }  
  
    usg.setpid(11084);  
    for (int i = 0; i < 10; i++)  
    {  
        float cpu = usg.get_cpu_usage();  
        printf("devenv.exe: %.2f%%\n", cpu);  
        Sleep(1000);  
    }  
      
    return 0;  
}  

标签:last,cpu,system,C++,CPUusage,time,使用率,CPU
From: https://www.cnblogs.com/kn-zheng/p/17001035.html

相关文章

  • 装饰模式javac++
    实验11:装饰模式本次实验属于模仿型实验,通过本次实验学生将掌握以下内容: 1、理解装饰模式的动机,掌握该模式的结构;2、能够利用装饰模式解决实际问题。 [实验任务一]:手......
  • windows平台下 c++获取 系统版本 网卡 内存 CPU 硬盘 显卡信息
    GetsysInfo.h:#ifndef_H_GETSYSINFO#define_H_GETSYSINFO#pragmaonce#include<afxtempl.h>classGetSysInfo{public:GetSysIn......
  • 跨平台C++ DLL导出宏
    #pragmaonce#ifdefined(__GNUC__)#define_DEPRECATED___attribute__((deprecated))#define_FORCE_INLINE___attribute__((always_inline))#elifdefined(_MSC_......
  • c++随笔测试(Corner of cpp)
    在c++17下,程序的输出是什么?(有可能编译出错,有可能输出未知,有可能是未定义行为)点击查看代码#include<iostream>voidfoo(unsignedint){std::cout<<"uint";}voidfo......
  • C++中map用法详解
    Map是c++的一个标准容器,她提供了很好一对一的关系,在一些程序中建立一个map可以起到事半功倍的效果,总结了一些map基本简单实用的操作!1.map最基本的构造函数;map<string,......
  • c++ 读取Ini文件
    头文件#include<atlstr.h> C++读取INI文件-疯封风-博客园(cnblogs.com)......
  • 获取本机内网、外网ip(C++)
    基础知识  电脑在局域网内,通过网关/路由器连接到Internet则ip分为内网ip、外网ip。通过ipconfig得到的为局域网ip。电脑直接拨号连接等,则本机通过ipconfig得到的就......
  • C++提取出std::map中的key集合
    std::map<std::string,uint32_t>dictionarystd::set<conststd::string*>keySet;//std::back_inserter(keyVector)std::transform(dictionary.begin(),dictiona......
  • c++通过DPI连接达梦数据库
    通过ODBC连接上数据库后,同事让我换内网电脑开发,又换了数据库给我,结果怎么都连不上数据库,又尝试了DPI连接达梦数据库的方式,连接上了,记录如下。连接代码#include"StdAfx.......
  • 【操作系统---并发编程】CPU cache结构和缓存一致性(MESI协议)
    转载自:https://blog.csdn.net/reliveIT/article/details/50450136?spm=1001.2014.3001.5506(三人行,必有我师) 一、cachecpucache已经发展到了三级缓存结构,基本上现在......