Linux C语言中sysinfo如何获取系统信息?

99ANYc3cd6
预计阅读时长 19 分钟
位置: 首页 C语言 正文

sysinfo 是什么?

sysinfo 是一个 Linux 系统调用,它通过 #include <sys/sysinfo.h> 头文件声明,它的主要作用是获取系统的整体运行状态,包括:

linux c语言 sysinfo
(图片来源网络,侵删)
  • 系统正常运行时间
  • 空闲内存量
  • 使用中的内存量
  • 共享内存量
  • 硬盘缓存大小
  • 总交换区大小
  • 空闲交换区大小
  • 进程总数
  • 正在运行的进程数

这些信息对于系统监控、性能分析和调试非常有用。


函数原型

#include <sys/sysinfo.h>
int sysinfo(struct sysinfo *info);

参数:

  • info: 指向一个 struct sysinfo 结构体的指针,该结构体会被函数填充,用于返回系统信息。

返回值:

  • 成功: 返回 0
  • 失败: 返回 -1,并设置 errno 来指示错误原因。

struct sysinfo 结构体详解

这是 sysinfo 函数的核心,你需要定义一个这个结构体的变量,并将其地址传递给函数,下面是该结构体在 64 位系统上的典型定义(具体成员的单位和类型可能因内核版本和架构略有不同):

linux c语言 sysinfo
(图片来源网络,侵删)
struct sysinfo {
    long uptime;         // 系统运行的总秒数
    unsigned long loads[3]; // 分别表示 1, 5, 15 分钟内的系统负载
    unsigned long totalram; // 总的物理内存大小(字节)
    unsigned long freeram;  // 空闲的物理内存大小(字节)
    unsigned long sharedram;// 共享的物理内存大小(字节)
    unsigned long bufferram;// 用于缓冲区的内存大小(字节)
    unsigned long totalswap; // 总的交换区大小(字节)
    unsigned long freeswap;  // 空闲的交换区大小(字节)
    unsigned short procs;    // 进程总数
    unsigned long totalhigh; // 保留字段,通常为0
    unsigned long freehigh;  // 保留字段,通常为0
    unsigned int mem_unit;   // 内存单位,通常为 1 (字节)
    char _f[20 - 2 * sizeof(long) - sizeof(int)]; // 填充字段,保持结构体大小一致
};

关键成员解释:

  • uptime: 自系统启动以来经过的秒数。
  • loads: 一个包含三个 unsigned long 值的数组,分别代表 1 分钟、5 分钟和 15 分钟的系统平均负载,负载值表示在特定时间间隔内,运行队列中平均有多少个进程在等待 CPU。
  • totalram / freeram: 系统总的物理内存和当前空闲的物理内存。
  • bufferram: Linux 内核用于缓冲块设备 I/O 的内存大小,这部分内存可以被快速回收,freeram + bufferram 可以看作是系统可用的“准空闲”内存。
  • totalswap / freeswap: 系统配置的交换区(虚拟内存)的总大小和当前空闲大小。
  • mem_unit: 这是一个非常重要的字段,它表示所有内存相关字段(totalram, freeram 等)的单位。在现代 Linux 系统上,这个值几乎总是 1 (字节),但为了代码的健壮性,最好在使用前检查它。

完整 C 语言示例代码

下面是一个完整的示例程序,它会调用 sysinfo 并打印出所有获取到的信息。

#include <stdio.h>
#include <sys/sysinfo.h>
#include <errno.h>
#include <string.h>
// 辅助函数,用于将字节转换为更易读的 KB, MB, GB 格式
void print_memory(unsigned long bytes) {
    const double kb = 1024.0;
    const double mb = kb * kb;
    const double gb = kb * mb;
    if (bytes >= gb) {
        printf("%.2f GB", bytes / gb);
    } else if (bytes >= mb) {
        printf("%.2f MB", bytes / mb);
    } else if (bytes >= kb) {
        printf("%.2f KB", bytes / kb);
    } else {
        printf("%lu Bytes", bytes);
    }
}
int main() {
    struct sysinfo info;
    // 调用 sysinfo 函数
    if (sysinfo(&info) != 0) {
        // 如果调用失败,打印错误信息
        perror("sysinfo error");
        return 1;
    }
    printf("=== System Information ===\n");
    // 打印系统运行时间
    printf("Uptime: %ld seconds (%.2f hours)\n", info.uptime, (double)info.uptime / 3600.0);
    // 打印系统负载
    printf("Load Average (1, 5, 15 min): %.2f, %.2f, %.2f\n",
           (double)info.loads[0] / (double)(1 << SI_LOAD_SHIFT),
           (double)info.loads[1] / (double)(1 << SI_LOAD_SHIFT),
           (double)info.loads[2] / (double)(1 << SI_LOAD_SHIFT));
    // 打印内存信息
    printf("\n--- Memory Info ---\n");
    printf("Memory Unit: %u\n", info.mem_unit); // 通常为 1
    printf("Total RAM: ");
    print_memory(info.totalram);
    printf("\nFree RAM: ");
    print_memory(info.freeram);
    printf("\nShared RAM: ");
    print_memory(info.sharedram);
    printf("\nBuffer RAM: ");
    print_memory(info.bufferram);
    // 可用内存 ≈ 空闲内存 + 缓冲内存
    unsigned long available_mem = info.freeram + info.bufferram;
    printf("\nApprox. Available Memory: ");
    print_memory(available_mem);
    printf("\n");
    // 打印交换区信息
    printf("\n--- Swap Info ---\n");
    printf("Total Swap: ");
    print_memory(info.totalswap);
    printf("\nFree Swap: ");
    print_memory(info.freeswap);
    printf("\n");
    // 打印进程信息
    printf("\n--- Process Info ---\n");
    printf("Total Processes: %hu\n", info.procs);
    return 0;
}

编译和运行:

# 编译程序
gcc -o sysinfo_example sysinfo_example.c
# 运行程序
./sysinfo_example

示例输出:

linux c语言 sysinfo
(图片来源网络,侵删)
=== System Information ===
Uptime: 12345 seconds (3.43 hours)
Load Average (1, 5, 15 min): 0.15, 0.20, 0.18
--- Memory Info ---
Memory Unit: 1
Total RAM: 7.81 GB
Free RAM: 1.20 GB
Shared RAM: 0 Bytes
Buffer RAM: 512.00 MB
Approx. Available Memory: 1.71 GB
--- Swap Info ---
Total Swap: 2.00 GB
Free Swap: 1.80 GB
--- Process Info ---
Total Processes: 256

sysinfo vs. /proc 文件系统

在 Linux 中,获取系统信息还有另一种常见方式:直接读取 /proc 文件系统中的虚拟文件。sysinfo/proc 各有优劣。

特性 sysinfo 系统调用 /proc 文件系统
接口 单一的函数调用,结构化返回数据。 需要打开、读取、解析文本文件。
数据格式 结构化的二进制数据,易于程序处理。 纯文本格式,便于人类阅读和 grep
开销 通常比解析文本文件更快,开销更小。 需要文件 I/O 操作,可能涉及用户态/内核态切换,开销稍大。
依赖性 标准 POSIX 扩展,但主要在 Linux 上可用。 Linux 特有,是内核的“调试窗口”。
信息量 信息固定,由 struct sysinfo 定义。 信息极其丰富,几乎包含内核的方方面面(如 /proc/cpuinfo, /proc/meminfo, /proc/stat 等)。
错误处理 通过 errno 返回错误码。 文件打开失败或读取错误,需要检查 fopen/read 的返回值。
  • 如果只需要 sysinfo 结构体中提供的那些基本信息,并且追求效率和简洁,优先使用 sysinfo
  • 如果需要更详细、更底层的系统信息(如 CPU 频率、每个 CPU 核心的负载、磁盘 I/O 统计等),或者你的程序需要高度可移植性(尽管 /proc 是 Linux 特有的),那么应该使用 /proc 文件系统。

/proc/meminfo 提供了比 sysinfo 更精确的内存信息,包括 MemAvailable(可用内存)、Slab 等。

-- 展开阅读全文 --
头像
织梦猫下载站整站dedecms模板
« 上一篇 12-07
C语言string库常用函数有哪些?
下一篇 » 12-07

相关文章

取消
微信二维码
支付宝二维码

目录[+]