V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
liuguangxuan
V2EX  ›  C++

不懂就要问,如何用 C++跨平台获取 CPU、内存使用率?

  •  
  •   liuguangxuan · 2020-05-06 11:04:51 +08:00 · 5213 次点击
    这是一个创建于 1663 天前的主题,其中的信息可能已经有所发展或是发生改变。

    想用 C++获取 CPU 、内存的使用率,要求跨平台( Windows 、Linux )。查到的解决办法如下:

    1. sigar 库,但是作者好像已经放弃维护了,没有文档可以参考,官网打不开。
    2. ACE 网络库提供了接口,但是只是获取 CPU 、内存使用率,显得有点儿太笨重了。
    3. 自己实现,根据宏来判断平台。然后调用系统接口。

    请教各位大佬,有没有更好的解决办法?

    27 条回复    2020-05-13 15:57:35 +08:00
    ysc3839
        1
    ysc3839  
       2020-05-06 11:13:57 +08:00
    首先目前来看 C++ 标准库中是没有相关功能的,所以最终只能调用系统 API 来获取。
    接下来就是看有没有现成的第三方库了,我没调查过不好说,如果没有的话,就只能自己实现了。
    根据你程序运行的平台来写,应该不会太难吧?只需要支持 Windows 和 Linux 的话不太难。
    Windows 的话内存使用率可以使用 GlobalMemoryStatusEx https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/nf-sysinfoapi-globalmemorystatusex 不过没有任务管理器那里那么详细。CPU 使用率 (准确说是一段时间内非空闲时间百分比) 可以用 GetSystemTimes 读了自己算出来。
    3dwelcome
        2
    3dwelcome  
       2020-05-06 11:20:25 +08:00
    linux 下统计内存使用率好像意义不大,因为基本都是被占满的状态。
    wtof
        3
    wtof  
       2020-05-06 11:26:18 +08:00
    这些功能本来就是平台相关的,其他库也无非就是第三种方法封装了一层实现
    个人倾向于第三种然后自己封一层接口
    Nitroethane
        4
    Nitroethane  
       2020-05-06 11:35:02 +08:00 via iPhone
    @3dwelcome 不了解就不要乱说,Linux 下空闲内存都被用作 file cache,在内存不足触发 watermark 的情况下,被用作 file cache 的大部分是能够被内核重新收回的

    Linux 下要获取各种数据的话需要自己去解析 /proc 下的各种文件,然后再通过阅读 /proc 的 manual 了解文件中每个字段的含义,比如内存信息的话 /proc/meminfo 。
    Windows 的话不清楚
    3dwelcome
        5
    3dwelcome  
       2020-05-06 11:39:43 +08:00
    @Nitroethane 我怎么就乱说了?真喵的奇怪了,都知道 linux 空闲内存会被用来加速,一般情况下服务器长期运行,所以很难统计真正空余内存有多少。
    这点和 windows 不一样,我就提一下,你还真是会喷人啊。
    Nitroethane
        6
    Nitroethane  
       2020-05-06 11:47:10 +08:00
    @3dwelcome #5 ?一脸懵逼,这年头 “不了解就不要乱说” 也算是喷人了么?既然你觉得我是在喷你,那我向你道歉好吧。话说回来, 建议了解一下 /proc/meminfo 里面所有字段的含义么和 Linux 的内存回收机制
    systemcall
        7
    systemcall  
       2020-05-06 11:47:19 +08:00 via Android
    @3dwelcome 并不是没意义吧。有时候内存泄漏了,不好修就趁没爆内存把那个进程杀了重开,这样起码还可以用,要求不太高的地方就可以这么搞
    wslzy007
        8
    wslzy007  
       2020-05-06 11:51:44 +08:00
    windows 下使用 winapi,cpu 线程数使用 GetSystemInfo ; linux 系使用 /proc/xxx 大法,自己计算。
    zhuangzhuang1988
        9
    zhuangzhuang1988  
       2020-05-06 12:00:41 +08:00   ❤️ 1
    osquery 这个项目里
    找找.
    3dwelcome
        10
    3dwelcome  
       2020-05-06 12:00:48 +08:00   ❤️ 6
    @Nitroethane 说者无心,听者有意。楼上有人支持你,我也向你道歉。可能我确实表述太过敷衍,也没描述清楚。
    同一个物体,在不同角度去看,是不一样的。太简单的回复写出来是一个意思,被人看又是另外一个意思了。
    Nitroethane
        11
    Nitroethane  
       2020-05-06 12:07:35 +08:00   ❤️ 5
    @3dwelcome #10 抱歉,其实我说话的方式也有点问题,不过就不用纠结这种小事了
    songjiaxin2008
        12
    songjiaxin2008  
       2020-05-06 12:27:17 +08:00   ❤️ 1
    可以参考 prometheus node_exporter
    https://github.com/prometheus/node_exporter
    evilic
        13
    evilic  
       2020-05-06 12:27:59 +08:00
    我觉得 @3dwelcome 说的没啥不对的……因为在我看来,那样的内存使用率确实意义不大。
    至少我读取虚拟机内存的信息的时候,就是这样的情况。

    读 /proc/ 目录?我在虚拟机外不会去读这些文件的。
    我只是把两个情况统一成一个问题看待了。
    tigerstudent
        14
    tigerstudent  
       2020-05-06 12:34:17 +08:00 via Android   ❤️ 3
    给 10 楼 11 楼两个乖宝宝都发了个感谢铜币。
    Chenamy2017
        15
    Chenamy2017  
       2020-05-06 12:40:35 +08:00
    也不难,自己封装吧,用别人库的代价大于自己实现的代价。
    UnknownR
        16
    UnknownR  
       2020-05-06 13:08:18 +08:00   ❤️ 1
    这个不复杂,自己封装下即可,windows 下 CPU 的话可以实例一个 performancecounter, 内存可以 query wmi,有内置属性,Win32_OperatingSystem 下的 FreePhysicalMemory 和 Win32_ComputerSystem 下的 TotalPhysicalMemory
    xdeng
        17
    xdeng  
       2020-05-06 13:58:05 +08:00
    #ifdef WIN32

    #else Mac

    #endif
    misaka19000
        18
    misaka19000  
       2020-05-06 14:06:09 +08:00   ❤️ 1
    @3dwelcome #9 这就是文字的坑爹之处,同样一段文字有时候在不同的人看来会有不同的感受,甚至于包含了正反两种截然不同的情绪,这大概也是互联网上面“杠精”越来越多的原因。因为在进行文字交流的时候总会伴随着大量的误解,但是由于文字这种交流渠道其自存在的及时性以及准确性方面的问题,有时候反而会使得这种误解进一步的加深。同时通过文字来进行解释或者说澄清本身也是一件非常麻烦的事情,因为在大部分时候我们都不太愿意花费精力去和一个陌生人去对某件事情进行解释(除非是在某种及其封闭的小圈子中),所以这大概也是互联网上戾气越来越重的原因~~~
    paoqi2048
        19
    paoqi2048  
       2020-05-06 14:06:09 +08:00
    自己实现吧,不用多少代码
    VYSE
        20
    VYSE  
       2020-05-06 14:51:43 +08:00
    参考 Python 跨平台实现 psutil.virtual_memory().available
    Dlad
        21
    Dlad  
       2020-05-06 15:47:38 +08:00
    有参考 cacti 吗?
    snmp 协议能实现吗?
    gamexg
        22
    gamexg  
       2020-05-06 15:53:04 +08:00   ❤️ 1
    c 的不知道,go 我用的是 https://github.com/shirou/gopsutil,windows 、linux 等系统都支持,可以参考下。
    wzzzx
        23
    wzzzx  
       2020-05-06 19:47:42 +08:00
    我之前用 Qt 也有这个需求,查资料时说是这些东西太平台相关性了,所以即便是 Qt 也没提供。自己写也不麻烦
    xcstream
        24
    xcstream  
       2020-05-06 22:47:52 +08:00
    选 3
    tianshiyeben
        25
    tianshiyeben  
       2020-05-07 09:29:14 +08:00
    sigar 用着没有问题啊。这个监控工具就用 sigar 来采集系统信息的,这就是我写的监控系统。
    https://github.com/tianshiyeben/wgcloud
    paoqi2048
        26
    paoqi2048  
       2020-05-07 11:14:29 +08:00
    @tianshiyeben sigar 在 GitHub 上的最后一次更新是 Jan 4, 2016
    kios
        27
    kios  
       2020-05-13 15:57:35 +08:00
    @gamexg 这个库我也用 感觉还不错
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1383 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 17:16 · PVG 01:16 · LAX 09:16 · JFK 12:16
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.