window 下查看指定程序的 CPU 使用情况

1、开发环境:window10 + QtCreator4.8.2 + Qt5.12.2

2、开发背景:满足查看指定程序运行过程中的 CPU 使用情况

3、实现方法:

  (1)通过程序名获取进程 ID

  (2)获取 CPU 核心数量

  (3)获取进程运行时间

  (4)统计进程运行时的 CPU 使用率并保存

  (5)实现代码和配置文件如下

//#include <stdafx.h>
#include <stdio.h>

#undef   UNICODE

#include <windows.h>
#include <stdint.h>
#include <tlhelp32.h>
#include <stdio.h>
#include <iostream>
#include <vector>

#include <QFile>
#include <QDebug>
#include <QDateTime>
#include <QSettings>
#include <QCoreApplication>

using namespace std;

typedef long long           int64_t;
typedef unsigned long long  uint64_t;

// 时间转换
static uint64_t file_time_2_utc(const FILETIME* ftime)
{
    LARGE_INTEGER li;

    li.LowPart = ftime->dwLowDateTime;
    li.HighPart = ftime->dwHighDateTime;
    return li.QuadPart;
}

DWORD GetProcessIDByName(const char* pName)
{
    HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    if (INVALID_HANDLE_VALUE == hSnapshot) {
        return NULL;
    }
    PROCESSENTRY32 pe = { sizeof(pe) };
    for (BOOL ret = Process32First(hSnapshot, &pe); ret; ret = Process32Next(hSnapshot, &pe))
    {
        if (strcmp(pe.szExeFile, pName) == 0)
        {
            CloseHandle(hSnapshot);
            return pe.th32ProcessID;
        }

        printf("%-6d %s\n", pe.th32ProcessID, pe.szExeFile);
    }
    CloseHandle(hSnapshot);
    return 0;
}



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

int get_cpu_usage(int pid)
{
    //cpu数量
    static int processor_count_ = -1;
    //上一次的时间
    static int64_t last_time_ = 0;
    static int64_t last_system_time_ = 0;

    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;

    int cpu = -1;

    if(processor_count_ == -1)
    {
        processor_count_ = get_processor_number();
    }

    GetSystemTimeAsFileTime(&now);

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
    if (!GetProcessTimes(hProcess, &creation_time, &exit_time, &kernel_time, &user_time))
    {
        return -1;
    }
    system_time = (file_time_2_utc(&kernel_time) + file_time_2_utc(&user_time))
        / processor_count_;
    time = file_time_2_utc(&now);

    if ((last_system_time_ == 0) || (last_time_ == 0))
    {
        last_system_time_ = system_time;
        last_time_ = time;
        return get_cpu_usage(pid);
    }

    system_time_delta = system_time - last_system_time_;
    time_delta = time - last_time_;

    if (time_delta == 0)
        return get_cpu_usage(pid);

    cpu = (int)((system_time_delta * 100 + time_delta / 2) / time_delta);
    last_system_time_ = system_time;
    last_time_ = time;
    return cpu;
}

int main()
{
    int cpu;
    int process_id;

    QString filePath = _pgmptr;
    filePath.remove("testcpu.exe");

    QString configPath = filePath + "/Setting.ini";

    /* 全新文件模式 旧文件存在直接删掉 */
    QFile fileConfig(configPath);
    if (!fileConfig.exists())
    {
        qWarning() << __PRETTY_FUNCTION__ << "文件不存在:" << configPath;
        return 0;
    }

    /* 文件生成 */
    QSettings setting(configPath, QSettings::IniFormat);
    setting.setIniCodec("UTF-8");

    /* 通用组数据读取 */
    setting.beginGroup("Process");
    QString process_name = setting.value("process_name").toString();
    process_name = process_name.split("#").first().simplified();
    process_name.remove("'");
    setting.endGroup();

    setting.beginGroup("Interval");
    QString interval_mString = setting.value("interval_m").toString();
    interval_mString = interval_mString.split("#").first().simplified();
    quint32 interval_m = interval_mString.toUInt();
    setting.endGroup();

    process_id = GetProcessIDByName(process_name.toLatin1());
    qDebug() << __PRETTY_FUNCTION__ << "process_id:" << process_id
             << process_name << process_name.toLatin1();

    if (process_id == 0)
    {
        qDebug() << __PRETTY_FUNCTION__ << "process_id abnormal:" << process_id;
        return 0;
    }

    QString savePath = filePath += "/test.txt";
    QFile fileSave(savePath);
    fileSave.remove();
    qDebug() << "savePath" << savePath;

    while(1)
    {
        cpu = get_cpu_usage(process_id);
        QString writeData = QString("%1 CPU: %2%")
                .arg(QDateTime::currentDateTime().toString("[yyyy-MM-dd hh:mm:ss.zzz]"))
                .arg(cpu, 2);
        qDebug() << writeData;

        fileSave.open(QIODevice::ReadWrite | QIODevice::Append);
        fileSave.write(writeData.toLatin1() + "\n");
        fileSave.flush();
        fileSave.close();

        Sleep(interval_m);
    }

    return 0;
}
[Process]
process_name = 'QQ.exe'                # 进程名

[Interval]
interval_m = 1000  # 监测频率,以毫秒为单位
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 C# 中,可以通过设置线程的优先级来控制程序使用 CPU 资源的优先级。可以使用 `Thread` 类的 `Priority` 属性来设置线程的优先级,取值范围为 `ThreadPriority.Lowest` 到 `ThreadPriority.Highest`。 以下是一个简单的示例代码: ```csharp using System; using System.Threading; class Program { static void Main() { // 设置主线程的优先级为最高 Thread.CurrentThread.Priority = ThreadPriority.Highest; // 开启两个线程并设置不同的优先级 Thread t1 = new Thread(new ThreadStart(Method1)); Thread t2 = new Thread(new ThreadStart(Method2)); t1.Priority = ThreadPriority.Lowest; t2.Priority = ThreadPriority.Normal; t1.Start(); t2.Start(); // 主线程等待两个线程执行完毕后退出 t1.Join(); t2.Join(); Console.WriteLine("主线程结束"); } static void Method1() { Console.WriteLine("线程1开始执行"); for (int i = 0; i < 100000000; i++) ; Console.WriteLine("线程1执行完毕"); } static void Method2() { Console.WriteLine("线程2开始执行"); for (int i = 0; i < 100000000; i++) ; Console.WriteLine("线程2执行完毕"); } } ``` 上述代码中,首先设置主线程的优先级为最高,然后创建两个线程 `t1` 和 `t2` 并设置不同的优先级。`t1` 线程的优先级最低,`t2` 线程的优先级为普通。在两个线程中分别使用一个简单的循环模拟计算,然后输出线程执行完毕的信息。在主线程中启动两个线程并等待它们执行完毕后退出。 在实际开发中,需要根据具体的应用场景和需求来设置线程的优先级,并进行适当的异常处理。在大多数情况下,不建议过度使用这种方法来占用 CPU 资源,应该尽量让 CPU 资源分配给其他进程和线程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值