【嵌入式Linux开发】通过原生/proc与系统命令获取CPU、内存及运行时间(Python实现)

本文已在 映翰通(InHand)IG502 工业网关上进行完整测试,代码可直接部署至同类嵌入式Linux设备。

在嵌入式Linux设备或服务器上,有时我们需要在不依赖额外API的情况下,通过系统底层接口获取CPU使用率、内存占用、系统运行时间等基础信息。本文将介绍一种完全基于Linux原生机制的方法,通过读取/proc/stat、执行freeuptime命令,使用Python实现轻量级的系统监控模块。该方法无需任何第三方库,适用于资源受限的嵌入式环境(如映翰通IG502等工业路由器)。

一、为什么选择“原生方式”?

  • 无依赖:不依赖psutil等第三方库,减少部署体积。
  • 兼容性强:所有Linux发行版均提供/proc虚拟文件系统和标准命令。
  • 实时准确:直接读取内核统计数据,延迟低。
  • 可控性高:可以精确控制采样间隔和计算逻辑。

二、核心实现原理

1. 获取内存信息 —— free命令

free -h 以人类可读方式输出内存总量、已用量、空闲量、缓存等。我们只需调用subprocess获取输出即可。

2. 获取系统启动时间 —— uptime命令

uptime -p 输出“up 1 day, 3:20”格式的运行时长,适合直接展示。

3. 获取CPU使用率 —— 读取/proc/stat

/proc/stat第一行记录了CPU从开机至今的各类时间(user、nice、system、idle、iowait等)。
计算公式

  • 采样间隔1秒,分别读取前后两次的/proc/stat
  • 总时间差 total_diff = 所有CPU时间之和的差值。
  • 空闲时间差 idle_diff = idle字段的差值。
  • CPU使用率 = (total_diff - idle_diff) / total_diff × 100%

三、完整Python代码(映翰通IG502验证版)

以下代码已在映翰通IG502设备上运行通过,可直接复制使用:
在这里插入图片描述

import subprocess
import time

# 可选:引入日志模块
# from common.Logger import logger

def get_memory_info():
    """执行 free -h 获取内存信息"""
    result = subprocess.run(['free', '-h'], capture_output=True, text=True)
    return result.stdout

def get_uptime():
    """执行 uptime -p 获取系统已运行时间"""
    result = subprocess.run(['uptime', '-p'], capture_output=True, text=True)
    return result.stdout.strip()

def get_cpu_usage(interval=1):
    """
    通过读取 /proc/stat 计算CPU使用率
    interval: 采样间隔(秒)
    """
    # 读取第一次 /proc/stat 的第一行(总CPU)
    with open('/proc/stat', 'r') as f:
        cpu_before = f.readline().strip().split()[1:]  # 跳过"cpu"字段
    before_idle = int(cpu_before[3])   # idle时间
    before_total = sum(map(int, cpu_before))

    time.sleep(interval)

    # 读取第二次
    with open('/proc/stat', 'r') as f:
        cpu_after = f.readline().strip().split()[1:]
    after_idle = int(cpu_after[3])
    after_total = sum(map(int, cpu_after))

    # 计算差值
    idle_diff = after_idle - before_idle
    total_diff = after_total - before_total
    if total_diff == 0:
        return 0.0
    usage = (total_diff - idle_diff) / total_diff * 100
    return usage

def get_system_info():
    """获取所有系统信息并打包为字典"""
    memory_info = get_memory_info()
    uptime_info = get_uptime()
    cpu_usage = get_cpu_usage()
    return {
        'memory_info': memory_info,
        'uptime_info': uptime_info,
        'cpu_usage': cpu_usage
    }

if __name__ == "__main__":
    system_info = get_system_info()
    print("Memory Info:")
    print(system_info['memory_info'])
    print("Uptime Info:")
    print(system_info['uptime_info'])
    print(f"CPU Usage: {system_info['cpu_usage']:.2f}%")
    
    # 如需将数据发布到MQTT,可取消下面的注释
    # topic = "/inhand/IG502/monitor"
    # QoS = 1
    # publish(topic, system_info, QoS)

四、在映翰通IG502上的实际运行输出

查看日志信息,观察输出:

在这里插入图片描述

经测试,CPU使用率计算结果与设备Web管理界面显示的值基本一致。

五、扩展与注意事项

  1. 多核CPU:上述代码只读取第一行(总CPU平均)。若要获取每个核心的使用率,可逐行读取/proc/stat中后续的cpu0cpu1等行,分别计算。映翰通IG502采用单核处理器,因此无需额外处理。
  2. CPU使用率精度:采样间隔过短(如0.1秒)可能引入波动,推荐1秒。
  3. free输出格式:不同Linux发行版的free -h输出列数可能略有差异,但主要信息不变。若需解析数值,可用free -b获取字节数后再处理。
  4. 权限问题:读取/proc/stat和执行freeuptime无需root权限,普通用户即可。
  5. 嵌入式优化:在映翰通IG502这类Flash空间有限的设备上,本脚本体积小巧(仅约1KB),非常适合集成到已有的Python应用中。

六、总结

通过/proc文件系统和标准Linux命令,我们可以用不到30行Python代码实现一个稳定、轻量的系统监控模块。该方法特别适合嵌入式网关、边缘计算设备、物联网采集器等项目。本文提供的代码已在映翰通IG502工业路由器上验证,可直接用于生产环境。

如果你手头也有类似的ARM Linux设备(如映翰通其他IG系列型号等),不妨直接复用上述代码。


希望这篇文章对你有帮助!有任何问题欢迎留言讨论。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐