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

(图片来源网络,侵删)
- 系统正常运行时间
- 空闲内存量
- 使用中的内存量
- 共享内存量
- 硬盘缓存大小
- 总交换区大小
- 空闲交换区大小
- 进程总数
- 正在运行的进程数
这些信息对于系统监控、性能分析和调试非常有用。
函数原型
#include <sys/sysinfo.h> int sysinfo(struct sysinfo *info);
参数:
info: 指向一个struct sysinfo结构体的指针,该结构体会被函数填充,用于返回系统信息。
返回值:
- 成功: 返回
0。 - 失败: 返回
-1,并设置errno来指示错误原因。
struct sysinfo 结构体详解
这是 sysinfo 函数的核心,你需要定义一个这个结构体的变量,并将其地址传递给函数,下面是该结构体在 64 位系统上的典型定义(具体成员的单位和类型可能因内核版本和架构略有不同):

(图片来源网络,侵删)
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
示例输出:

(图片来源网络,侵删)
=== 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 等。
