sysfs 和 sysinfo 函数详解
1. 函数介绍
sysfs
sysfs
是Linux内核提供的虚拟文件系统,用于导出内核对象的信息到用户空间。它以文件和目录的形式呈现系统硬件、驱动程序、设备状态等信息,是现代Linux系统管理和监控的重要接口。
sysinfo
sysinfo
是Linux系统调用,用于获取系统的整体统计信息,包括内存使用情况、系统负载、运行时间等。它提供了一种编程方式来获取系统状态信息。
2. 函数原型
sysfs
#include <sysfs/libsysfs.h> // 需要安装libsysfs-dev包
// sysfs库函数(非系统调用)
struct sysfs_bus *sysfs_open_bus(const char *name);
struct sysfs_device *sysfs_open_device(const char *bus_name, const char *dev_name);
char *sysfs_get_device_attr(const char *devpath, const char *attr_name);
sysinfo
#include <sys/sysinfo.h>
int sysinfo(struct sysinfo *info);
3. 功能
sysfs
- 提供内核对象的结构化信息访问
- 导出硬件设备、驱动程序、总线等信息
- 支持动态查询设备状态和属性
sysinfo
- 获取系统内存使用统计
- 查询系统负载和运行时间
- 获取进程和用户统计信息
4. 参数
sysfs
- *const char name: 总线或设备名称
- *const char devpath: 设备路径
- *const char attr_name: 属性名称
sysinfo
- *struct sysinfo info: 指向sysinfo结构的指针
5. 返回值
sysfs
- 成功: 返回相应的句柄或字符串
- 失败: 返回NULL,并设置errno
sysinfo
- 成功: 返回0
- 失败: 返回-1,并设置errno
6. 相似函数,或关联函数
sysfs相关:
- opendir/readdir: 目录遍历
- open/read: 文件读取
- /sys/: sysfs挂载点
sysinfo相关:
- getloadavg: 获取系统负载平均值
- getrusage: 获取资源使用情况
- /proc/: procfs文件系统
7. 示例代码
示例1:基础sysinfo使用
#include <sys/sysinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
/**
* 显示系统信息
*/
void show_system_info() {
struct sysinfo si;
time_t current_time;
char time_str[64];
printf("=== 系统信息 ===\n");
// 获取系统信息
if (sysinfo(&si) == -1) {
perror("获取系统信息失败");
return;
}
// 显示时间信息
current_time = time(NULL);
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", localtime(¤t_time));
printf("当前时间: %s\n", time_str);
// 显示启动时间
time_t boot_time = current_time - si.uptime;
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", localtime(&boot_time));
printf("系统启动时间: %s\n", time_str);
printf("系统运行时间: %ld 天 %ld 小时 %ld 分钟\n",
si.uptime / 86400,
(si.uptime % 86400) / 3600,
(si.uptime % 3600) / 60);
// 显示负载信息
printf("\n系统负载:\n");
printf(" 1分钟平均负载: %.2f\n", (double)si.loads[0] / (1 << SI_LOAD_SHIFT));
printf(" 5分钟平均负载: %.2f\n", (double)si.loads[1] / (1 << SI_LOAD_SHIFT));
printf(" 15分钟平均负载: %.2f\n", (double)si.loads[2] / (1 << SI_LOAD_SHIFT));
// 显示内存信息
printf("\n内存信息:\n");
printf(" 总内存: %.2f GB\n", si.totalram * si.mem_unit / (1024.0 * 1024.0 * 1024.0));
printf(" 可用内存: %.2f GB\n", si.freeram * si.mem_unit / (1024.0 * 1024.0 * 1024.0));
printf(" 共享内存: %.2f GB\n", si.sharedram * si.mem_unit / (1024.0 * 1024.0 * 1024.0));
printf(" 缓冲区内存: %.2f GB\n", si.bufferram * si.mem_unit / (1024.0 * 1024.0 * 1024.0));
// 显示交换信息
printf("\n交换信息:\n");
printf(" 总交换空间: %.2f GB\n", si.totalswap * si.mem_unit / (1024.0 * 1024.0 * 1024.0));
printf(" 可用交换空间: %.2f GB\n", si.freeswap * si.mem_unit / (1024.0 * 1024.0 * 1024.0));
// 显示进程信息
printf("\n进程信息:\n");
printf(" 当前进程数: %d\n", si.procs);
printf("\n");
}
/**
* 演示基础sysinfo使用方法
*/
int demo_sysinfo_basic() {
printf("=== 基础sysinfo使用示例 ===\n");
// 显示系统信息
show_system_info();
// 演示多次查询
printf("连续查询系统信息:\n");
for (int i = 0; i < 3; i++) {
struct sysinfo si;
if (sysinfo(&si) == 0) {
printf(" 第 %d 次查询:\n", i + 1);
printf(" 运行时间: %ld 秒\n", si.uptime);
printf(" 可用内存: %.2f MB\n",
si.freeram * si.mem_unit / (1024.0 * 1024.0));
printf(" 当前进程: %d\n", si.procs);
} else {
printf(" 第 %d 次查询失败: %s\n", i + 1, strerror(errno));
}
if (i < 2) sleep(2); // 间隔查询
}
return 0;
}
int main() {
return demo_sysinfo_basic();
}
示例2:内存监控工具
#include <sys/sysinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
/**
* 内存使用统计结构
*/
typedef struct {
unsigned long total_ram_mb;
unsigned long free_ram_mb;
unsigned long used_ram_mb;
unsigned long shared_ram_mb;
unsigned long buffer_ram_mb;
unsigned long total_swap_mb;
unsigned long free_swap_mb;
unsigned long used_swap_mb;
double ram_usage_percent;
double swap_usage_percent;
} memory_stats_t;
/**
* 获取内存统计信息
*/
int get_memory_stats(memory_stats_t *stats) {
struct sysinfo si;
if (sysinfo(&si) == -1) {
return -1;
}
// 转换为MB
unsigned long mem_unit = si.mem_unit ? si.mem_unit : 1;
stats->total_ram_mb = si.totalram * mem_unit / (1024 * 1024);
stats->free_ram_mb = si.freeram * mem_unit / (1024 * 1024);
stats->used_ram_mb = stats->total_ram_mb - stats->free_ram_mb;
stats->shared_ram_mb = si.sharedram * mem_unit / (1024 * 1024);
stats->buffer_ram_mb = si.bufferram * mem_unit / (1024 * 1024);
stats->total_swap_mb = si.totalswap * mem_unit / (1024 * 1024);
stats->free_swap_mb = si.freeswap * mem_unit / (1024 * 1024);
stats->used_swap_mb = stats->total_swap_mb - stats->free_swap_mb;
// 计算使用率
stats->ram_usage_percent = stats->total_ram_mb > 0 ?
(double)stats->used_ram_mb / stats->total_ram_mb * 100 : 0;
stats->swap_usage_percent = stats->total_swap_mb > 0 ?
(double)stats->used_swap_mb / stats->total_swap_mb * 100 : 0;
return 0;
}
/**
* 显示内存统计信息
*/
void show_memory_stats(const memory_stats_t *stats) {
printf("内存统计信息:\n");
printf(" 物理内存:\n");
printf(" 总量: %lu MB\n", stats->total_ram_mb);
printf(" 已用: %lu MB (%.1f%%)\n", stats->used_ram_mb, stats->ram_usage_percent);
printf(" 可用: %lu MB\n", stats->free_ram_mb);
printf(" 共享: %lu MB\n", stats->shared_ram_mb);
printf(" 缓冲: %lu MB\n", stats->buffer_ram_mb);
printf(" 交换空间:\n");
printf(" 总量: %lu MB\n", stats->total_swap_mb);
printf(" 已用: %lu MB (%.1f%%)\n", stats->used_swap_mb, stats->swap_usage_percent);
printf(" 可用: %lu MB\n", stats->free_swap_mb);
}
/**
* 内存监控警报
*/
void check_memory_alerts(const memory_stats_t *stats) {
printf("\n内存警报检查:\n");
// RAM使用率警报
if (stats->ram_usage_percent > 90) {
printf(" ⚠ 警告: RAM使用率过高 (%.1f%%)\n", stats->ram_usage_percent);
} else if (stats->ram_usage_percent > 80) {
printf(" ℹ 提示: RAM使用率较高 (%.1f%%)\n", stats->ram_usage_percent);
} else {
printf(" ✓ RAM使用率正常 (%.1f%%)\n", stats->ram_usage_percent);
}
// 交换空间使用率警报
if (stats->swap_usage_percent > 80) {
printf(" ⚠ 警告: 交换空间使用率过高 (%.1f%%)\n", stats->swap_usage_percent);
} else if (stats->swap_usage_percent > 50) {
printf(" ℹ 提示: 交换空间使用率较高 (%.1f%%)\n", stats->swap_usage_percent);
} else {
printf(" ✓ 交换空间使用率正常 (%.1f%%)\n", stats->swap_usage_percent);
}
// 内存不足警报
if (stats->free_ram_mb < 100) {
printf(" ⚠ 警告: 可用内存不足 (%lu MB)\n", stats->free_ram_mb);
}
}
/**
* 演示内存监控工具
*/
int demo_memory_monitor() {
memory_stats_t stats;
printf("=== 内存监控工具演示 ===\n");
// 单次内存统计
printf("1. 当前内存状态:\n");
if (get_memory_stats(&stats) == 0) {
show_memory_stats(&stats);
check_memory_alerts(&stats);
} else {
printf("获取内存统计失败: %s\n", strerror(errno));
return -1;
}
// 连续监控演示
printf("\n2. 连续内存监控演示:\n");
printf("监控5次,每次间隔3秒:\n");
for (int i = 0; i < 5; i++) {
if (get_memory_stats(&stats) == 0) {
time_t now = time(NULL);
char time_str[32];
strftime(time_str, sizeof(time_str), "%H:%M:%S", localtime(&now));
printf("[%s] 第 %d 次监控:\n", time_str, i + 1);
printf(" RAM: %lu/%lu MB (%.1f%%)\n",
stats.used_ram_mb, stats.total_ram_mb, stats.ram_usage_percent);
printf(" Swap: %lu/%lu MB (%.1f%%)\n",
stats.used_swap_mb, stats.total_swap_mb, stats.swap_usage_percent);
// 检查警报
if (stats.ram_usage_percent > 90 || stats.swap_usage_percent > 80) {
printf(" ⚠ 触发内存警报\n");
}
} else {
printf("第 %d 次监控失败: %s\n", i + 1, strerror(errno));
}
if (i < 4) sleep(3);
}
// 内存使用趋势分析
printf("\n3. 内存使用趋势分析:\n");
printf("历史数据分析:\n");
unsigned long max_ram_usage = 0;
unsigned long min_ram_usage = (unsigned long)-1;
double total_ram_usage = 0;
int sample_count = 0;
for (int i = 0; i < 5; i++) {
if (get_memory_stats(&stats) == 0) {
if (stats.used_ram_mb > max_ram_usage) {
max_ram_usage = stats.used_ram_mb;
}
if (stats.used_ram_mb < min_ram_usage) {
min_ram_usage = stats.used_ram_mb;
}
total_ram_usage += stats.ram_usage_percent;
sample_count++;
}
sleep(1);
}
if (sample_count > 0) {
printf(" 最大RAM使用: %lu MB\n", max_ram_usage);
printf(" 最小RAM使用: %lu MB\n", min_ram_usage);
printf(" 平均RAM使用率: %.1f%%\n", total_ram_usage / sample_count);
}
return 0;
}
int main() {
return demo_memory_monitor();
}
示例3:系统负载监控
#include <sys/sysinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
/**
* 系统负载统计结构
*/
typedef struct {
double load_avg_1min;
double load_avg_5min;
double load_avg_15min;
unsigned long uptime_seconds;
unsigned int process_count;
time_t boot_time;
} system_load_stats_t;
/**
* 获取系统负载统计
*/
int get_system_load_stats(system_load_stats_t *stats) {
struct sysinfo si;
if (sysinfo(&si) == -1) {
return -1;
}
// 计算负载平均值
stats->load_avg_1min = (double)si.loads[0] / (1 << SI_LOAD_SHIFT);
stats->load_avg_5min = (double)si.loads[1] / (1 << SI_LOAD_SHIFT);
stats->load_avg_15min = (double)si.loads[2] / (1 << SI_LOAD_SHIFT);
// 系统运行时间
stats->uptime_seconds = si.uptime;
stats->boot_time = time(NULL) - si.uptime;
// 进程数
stats->process_count = si.procs;
return 0;
}
/**
* 显示系统负载统计
*/
void show_system_load_stats(const system_load_stats_t *stats) {
char boot_time_str[64];
char current_time_str[64];
strftime(boot_time_str, sizeof(boot_time_str), "%Y-%m-%d %H:%M:%S",
localtime(&stats->boot_time));
printf("系统负载统计:\n");
printf(" 系统启动时间: %s\n", boot_time_str);
unsigned long days = stats->uptime_seconds / 86400;
unsigned long hours = (stats->uptime_seconds % 86400) / 3600;
unsigned long minutes = (stats->uptime_seconds % 3600) / 60;
printf(" 系统运行时间: %lu 天 %lu 小时 %lu 分钟\n", days, hours, minutes);
printf(" 系统负载平均值:\n");
printf(" 1分钟: %.2f\n", stats->load_avg_1min);
printf(" 5分钟: %.2f\n", stats->load_avg_5min);
printf(" 15分钟: %.2f\n", stats->load_avg_15min);
printf(" 当前进程数: %u\n", stats->process_count);
}
/**
* 分析系统负载状态
*/
void analyze_system_load(const system_load_stats_t *stats, int cpu_count) {
printf("\n系统负载分析:\n");
// 1分钟负载分析
double load_per_cpu_1min = stats->load_avg_1min / cpu_count;
if (load_per_cpu_1min > 1.0) {
printf(" ⚠ 1分钟负载警告: 每CPU负载 %.2f (> 1.0)\n", load_per_cpu_1min);
} else if (load_per_cpu_1min > 0.7) {
printf(" ℹ 1分钟负载提示: 每CPU负载 %.2f (较高)\n", load_per_cpu_1min);
} else {
printf(" ✓ 1分钟负载正常: 每CPU负载 %.2f\n", load_per_cpu_1min);
}
// 5分钟负载分析
double load_per_cpu_5min = stats->load_avg_5min / cpu_count;
if (load_per_cpu_5min > 1.0) {
printf(" ⚠ 5分钟负载警告: 每CPU负载 %.2f (> 1.0)\n", load_per_cpu_5min);
} else if (load_per_cpu_5min > 0.7) {
printf(" ℹ 5分钟负载提示: 每CPU负载 %.2f (较高)\n", load_per_cpu_5min);
} else {
printf(" ✓ 5分钟负载正常: 每CPU负载 %.2f\n", load_per_cpu_5min);
}
// 15分钟负载分析
double load_per_cpu_15min = stats->load_avg_15min / cpu_count;
if (load_per_cpu_15min > 1.0) {
printf(" ⚠ 15分钟负载警告: 每CPU负载 %.2f (> 1.0)\n", load_per_cpu_15min);
} else if (load_per_cpu_15min > 0.7) {
printf(" ℹ 15分钟负载提示: 每CPU负载 %.2f (较高)\n", load_per_cpu_15min);
} else {
printf(" ✓ 15分钟负载正常: 每CPU负载 %.2f\n", load_per_cpu_15min);
}
// 进程数分析
if (stats->process_count > 1000) {
printf(" ⚠ 进程数警告: 当前有 %u 个进程\n", stats->process_count);
} else if (stats->process_count > 500) {
printf(" ℹ 进程数提示: 当前有 %u 个进程\n", stats->process_count);
} else {
printf(" ✓ 进程数正常: 当前有 %u 个进程\n", stats->process_count);
}
}
/**
* 演示系统负载监控
*/
int demo_system_load_monitoring() {
system_load_stats_t stats;
int cpu_count = sysconf(_SC_NPROCESSORS_ONLN);
printf("=== 系统负载监控演示 ===\n");
printf("CPU核心数: %d\n", cpu_count);
// 单次负载统计
printf("\n1. 当前系统负载状态:\n");
if (get_system_load_stats(&stats) == 0) {
show_system_load_stats(&stats);
analyze_system_load(&stats, cpu_count);
} else {
printf("获取系统负载统计失败: %s\n", strerror(errno));
return -1;
}
// 连续负载监控
printf("\n2. 连续负载监控演示:\n");
printf("监控10次,每次间隔2秒:\n");
double max_load_1min = 0, min_load_1min = 999;
double total_load_1min = 0;
int sample_count = 0;
for (int i = 0; i < 10; i++) {
if (get_system_load_stats(&stats) == 0) {
time_t now = time(NULL);
char time_str[32];
strftime(time_str, sizeof(time_str), "%H:%M:%S", localtime(&now));
printf("[%s] 第 %d 次监控:\n", time_str, i + 1);
printf(" 负载: %.2f %.2f %.2f\n",
stats.load_avg_1min, stats.load_avg_5min, stats.load_avg_15min);
printf(" 进程: %u\n", stats.process_count);
// 统计负载数据
if (stats.load_avg_1min > max_load_1min) {
max_load_1min = stats.load_avg_1min;
}
if (stats.load_avg_1min < min_load_1min) {
min_load_1min = stats.load_avg_1min;
}
total_load_1min += stats.load_avg_1min;
sample_count++;
} else {
printf("第 %d 次监控失败: %s\n", i + 1, strerror(errno));
}
if (i < 9) sleep(2);
}
// 负载趋势分析
printf("\n3. 负载趋势分析:\n");
if (sample_count > 0) {
printf(" 1分钟负载范围: %.2f - %.2f\n", min_load_1min, max_load_1min);
printf(" 1分钟负载平均: %.2f\n", total_load_1min / sample_count);
printf(" 负载波动幅度: %.2f\n", max_load_1min - min_load_1min);
}
// 负载等级判断
printf("\n4. 负载等级判断:\n");
if (sample_count > 0) {
double avg_load = total_load_1min / sample_count;
double load_per_cpu = avg_load / cpu_count;
if (load_per_cpu > 1.5) {
printf(" 💥 系统负载极重: 每CPU平均负载 %.2f\n", load_per_cpu);
} else if (load_per_cpu > 1.0) {
printf(" ⚠ 系统负载较重: 每CPU平均负载 %.2f\n", load_per_cpu);
} else if (load_per_cpu > 0.7) {
printf(" ℹ 系统负载中等: 每CPU平均负载 %.2f\n", load_per_cpu);
} else {
printf(" ✓ 系统负载轻松: 每CPU平均负载 %.2f\n", load_per_cpu);
}
}
return 0;
}
int main() {
return demo_system_load_monitoring();
}
示例4:基础sysfs使用
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
/**
* 读取sysfs文件内容
*/
int read_sysfs_file(const char *path, char *buffer, size_t buffer_size) {
int fd;
ssize_t bytes_read;
fd = open(path, O_RDONLY);
if (fd == -1) {
return -1;
}
bytes_read = read(fd, buffer, buffer_size - 1);
if (bytes_read == -1) {
close(fd);
return -1;
}
buffer[bytes_read] = '\0';
// 移除末尾的换行符
if (bytes_read > 0 && buffer[bytes_read - 1] == '\n') {
buffer[bytes_read - 1] = '\0';
}
close(fd);
return 0;
}
/**
* 显示CPU信息
*/
void show_cpu_info() {
DIR *dir;
struct dirent *entry;
char path[256];
char buffer[256];
printf("=== CPU信息 ===\n");
// 读取CPU基本信息
if (read_sysfs_file("/sys/devices/system/cpu/online", buffer, sizeof(buffer)) == 0) {
printf("在线CPU: %s\n", buffer);
}
if (read_sysfs_file("/sys/devices/system/cpu/offline", buffer, sizeof(buffer)) == 0) {
if (strlen(buffer) > 0) {
printf("离线CPU: %s\n", buffer);
}
}
// 遍历CPU目录
dir = opendir("/sys/devices/system/cpu");
if (dir) {
int cpu_count = 0;
while ((entry = readdir(dir)) != NULL) {
if (strncmp(entry->d_name, "cpu", 3) == 0 &&
entry->d_name[3] >= '0' && entry->d_name[3] <= '9') {
cpu_count++;
// 读取CPU频率信息
snprintf(path, sizeof(path),
"/sys/devices/system/cpu/%s/cpufreq/scaling_cur_freq",
entry->d_name);
if (read_sysfs_file(path, buffer, sizeof(buffer)) == 0) {
long freq_khz = atol(buffer);
printf("CPU %s 当前频率: %.2f MHz\n",
entry->d_name, freq_khz / 1000.0);
}
// 读取CPU在线状态
snprintf(path, sizeof(path),
"/sys/devices/system/cpu/%s/online",
entry->d_name);
if (read_sysfs_file(path, buffer, sizeof(buffer)) == 0) {
printf("CPU %s 在线状态: %s\n",
entry->d_name, atoi(buffer) ? "在线" : "离线");
}
}
}
printf("CPU总数: %d\n", cpu_count);
closedir(dir);
}
printf("\n");
}
/**
* 显示内存信息
*/
void show_memory_info() {
char buffer[256];
printf("=== 内存信息 ===\n");
// 读取内存块信息
if (read_sysfs_file("/sys/devices/system/memory/block_size_bytes", buffer, sizeof(buffer)) == 0) {
unsigned long block_size = strtoul(buffer, NULL, 16);
printf("内存块大小: %lu 字节 (%.2f MB)\n", block_size, block_size / (1024.0 * 1024.0));
}
// 遍历内存块
DIR *dir = opendir("/sys/devices/system/memory");
if (dir) {
struct dirent *entry;
int online_count = 0, total_count = 0;
while ((entry = readdir(dir)) != NULL) {
if (strncmp(entry->d_name, "memory", 6) == 0) {
total_count++;
char path[256];
snprintf(path, sizeof(path),
"/sys/devices/system/memory/%s/state", entry->d_name);
if (read_sysfs_file(path, buffer, sizeof(buffer)) == 0) {
if (strcmp(buffer, "online") == 0) {
online_count++;
}
}
}
}
printf("内存块总数: %d\n", total_count);
printf("在线内存块: %d\n", online_count);
printf("离线内存块: %d\n", total_count - online_count);
closedir(dir);
}
printf("\n");
}
/**
* 显示块设备信息
*/
void show_block_devices() {
printf("=== 块设备信息 ===\n");
DIR *dir = opendir("/sys/block");
if (dir) {
struct dirent *entry;
printf("块设备列表:\n");
while ((entry = readdir(dir)) != NULL) {
if (entry->d_name[0] != '.') {
char path[256];
char buffer[256];
// 读取设备大小
snprintf(path, sizeof(path), "/sys/block/%s/size", entry->d_name);
if (read_sysfs_file(path, buffer, sizeof(buffer)) == 0) {
unsigned long sectors = atol(buffer);
double size_gb = sectors * 512.0 / (1024.0 * 1024.0 * 1024.0);
printf(" %s: %.2f GB (%lu 扇区)\n", entry->d_name, size_gb, sectors);
} else {
printf(" %s: (无法获取大小)\n", entry->d_name);
}
// 读取设备类型
snprintf(path, sizeof(path), "/sys/block/%s/queue/rotational", entry->d_name);
if (read_sysfs_file(path, buffer, sizeof(buffer)) == 0) {
if (atoi(buffer) == 1) {
printf(" 类型: 机械硬盘\n");
} else {
printf(" 类型: 固态硬盘\n");
}
}
}
}
closedir(dir);
}
printf("\n");
}
/**
* 演示基础sysfs使用方法
*/
int demo_sysfs_basic() {
printf("=== 基础sysfs使用示例 ===\n");
// 检查sysfs是否挂载
if (access("/sys", F_OK) == -1) {
printf("sysfs未挂载或不可访问\n");
return -1;
}
printf("sysfs挂载点: /sys\n");
// 显示CPU信息
show_cpu_info();
// 显示内存信息
show_memory_info();
// 显示块设备信息
show_block_devices();
// 演示读取特定属性
printf("=== 特定属性读取演示 ===\n");
struct {
const char *path;
const char *description;
} attributes[] = {
{"/sys/class/dmi/id/product_name", "产品名称"},
{"/sys/class/dmi/id/product_version", "产品版本"},
{"/sys/class/dmi/id/bios_vendor", "BIOS厂商"},
{"/sys/class/dmi/id/bios_version", "BIOS版本"},
{"/sys/kernel/mm/transparent_hugepage/enabled", "透明大页状态"},
{NULL, NULL}
};
for (int i = 0; attributes[i].path; i++) {
char buffer[256];
if (read_sysfs_file(attributes[i].path, buffer, sizeof(buffer)) == 0) {
printf("%s: %s\n", attributes[i].description, buffer);
} else {
printf("%s: 无法读取 (%s)\n", attributes[i].description, strerror(errno));
}
}
return 0;
}
int main() {
return demo_sysfs_basic();
}
示例5:综合系统监控工具
#include <sys/sysinfo.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <dirent.h>
#include <fcntl.h>
/**
* 综合系统信息结构
*/
typedef struct {
// 系统基本信息
time_t current_time;
time_t boot_time;
unsigned long uptime_seconds;
// 内存信息
unsigned long total_ram_mb;
unsigned long free_ram_mb;
unsigned long used_ram_mb;
unsigned long total_swap_mb;
unsigned long free_swap_mb;
unsigned long used_swap_mb;
double ram_usage_percent;
double swap_usage_percent;
// 负载信息
double load_avg_1min;
double load_avg_5min;
double load_avg_15min;
unsigned int process_count;
// 硬件信息
int cpu_count;
int online_cpu_count;
char hostname[256];
} system_info_t;
/**
* 获取综合系统信息
*/
int get_system_info(system_info_t *info) {
struct sysinfo si;
// 获取系统时间
info->current_time = time(NULL);
// 获取sysinfo信息
if (sysinfo(&si) == -1) {
return -1;
}
// 系统基本信息
info->uptime_seconds = si.uptime;
info->boot_time = info->current_time - si.uptime;
// 内存信息
unsigned long mem_unit = si.mem_unit ? si.mem_unit : 1;
info->total_ram_mb = si.totalram * mem_unit / (1024 * 1024);
info->free_ram_mb = si.freeram * mem_unit / (1024 * 1024);
info->used_ram_mb = info->total_ram_mb - info->free_ram_mb;
info->total_swap_mb = si.totalswap * mem_unit / (1024 * 1024);
info->free_swap_mb = si.freeswap * mem_unit / (1024 * 1024);
info->used_swap_mb = info->total_swap_mb - info->free_swap_mb;
info->ram_usage_percent = info->total_ram_mb > 0 ?
(double)info->used_ram_mb / info->total_ram_mb * 100 : 0;
info->swap_usage_percent = info->total_swap_mb > 0 ?
(double)info->used_swap_mb / info->total_swap_mb * 100 : 0;
// 负载信息
info->load_avg_1min = (double)si.loads[0] / (1 << SI_LOAD_SHIFT);
info->load_avg_5min = (double)si.loads[1] / (1 << SI_LOAD_SHIFT);
info->load_avg_15min = (double)si.loads[2] / (1 << SI_LOAD_SHIFT);
info->process_count = si.procs;
// 硬件信息
info->cpu_count = sysconf(_SC_NPROCESSORS_ONLN);
info->online_cpu_count = info->cpu_count; // 简化处理
// 主机名
gethostname(info->hostname, sizeof(info->hostname) - 1);
return 0;
}
/**
* 显示综合系统信息
*/
void show_system_info(const system_info_t *info) {
char time_str[64];
char boot_time_str[64];
printf("=========================================\n");
printf(" 系统监控报告\n");
printf("=========================================\n");
// 时间信息
strftime(time_str, sizeof(time_str), "%Y-%m-%d %H:%M:%S", localtime(&info->current_time));
strftime(boot_time_str, sizeof(boot_time_str), "%Y-%m-%d %H:%M:%S", localtime(&info->boot_time));
printf("主机名: %s\n", info->hostname);
printf("当前时间: %s\n", time_str);
printf("启动时间: %s\n", boot_time_str);
unsigned long days = info->uptime_seconds / 86400;
unsigned long hours = (info->uptime_seconds % 86400) / 3600;
unsigned long minutes = (info->uptime_seconds % 3600) / 60;
printf("运行时间: %lu 天 %lu 小时 %lu 分钟\n", days, hours, minutes);
// CPU信息
printf("\nCPU信息:\n");
printf(" CPU核心数: %d\n", info->cpu_count);
printf(" 在线CPU数: %d\n", info->online_cpu_count);
// 内存信息
printf("\n内存信息:\n");
printf(" 物理内存: %lu MB / %lu MB (%.1f%%)\n",
info->used_ram_mb, info->total_ram_mb, info->ram_usage_percent);
printf(" 交换空间: %lu MB / %lu MB (%.1f%%)\n",
info->used_swap_mb, info->total_swap_mb, info->swap_usage_percent);
// 负载信息
printf("\n系统负载:\n");
printf(" 1分钟平均负载: %.2f\n", info->load_avg_1min);
printf(" 5分钟平均负载: %.2f\n", info->load_avg_5min);
printf(" 15分钟平均负载: %.2f\n", info->load_avg_15min);
printf(" 当前进程数: %u\n", info->process_count);
// 系统健康状态
printf("\n系统健康状态:\n");
// 内存健康检查
if (info->ram_usage_percent > 90) {
printf(" ⚠ 内存使用率过高: %.1f%%\n", info->ram_usage_percent);
} else if (info->ram_usage_percent > 80) {
printf(" ℹ 内存使用率较高: %.1f%%\n", info->ram_usage_percent);
} else {
printf(" ✓ 内存使用率正常: %.1f%%\n", info->ram_usage_percent);
}
// 交换空间健康检查
if (info->swap_usage_percent > 50) {
printf(" ⚠ 交换空间使用过多: %.1f%%\n", info->swap_usage_percent);
} else if (info->swap_usage_percent > 20) {
printf(" ℹ 交换空间使用较多: %.1f%%\n", info->swap_usage_percent);
} else {
printf(" ✓ 交换空间使用正常: %.1f%%\n", info->swap_usage_percent);
}
// 负载健康检查
double load_per_cpu = info->load_avg_1min / info->cpu_count;
if (load_per_cpu > 1.5) {
printf(" ⚠ 系统负载过重: 每CPU负载 %.2f\n", load_per_cpu);
} else if (load_per_cpu > 1.0) {
printf(" ℹ 系统负载中等: 每CPU负载 %.2f\n", load_per_cpu);
} else {
printf(" ✓ 系统负载正常: 每CPU负载 %.2f\n", load_per_cpu);
}
printf("=========================================\n\n");
}
/**
* 实时监控模式
*/
void real_time_monitoring(int duration_seconds, int interval_seconds) {
system_info_t info;
time_t start_time = time(NULL);
time_t current_time;
int report_count = 0;
printf("=== 实时系统监控 ===\n");
printf("监控时长: %d 秒\n", duration_seconds);
printf("监控间隔: %d 秒\n", interval_seconds);
printf("开始监控...\n\n");
while ((current_time = time(NULL)) - start_time < duration_seconds) {
if (get_system_info(&info) == 0) {
report_count++;
printf("[第 %d 次监控报告] ", report_count);
show_system_info(&info);
} else {
printf("获取系统信息失败: %s\n", strerror(errno));
}
// 等待下次监控
sleep(interval_seconds);
}
printf("监控完成,共生成 %d 份报告\n", report_count);
}
/**
* 演示综合系统监控工具
*/
int demo_comprehensive_monitor() {
system_info_t info;
printf("=== 综合系统监控工具演示 ===\n");
// 单次系统信息获取
printf("1. 当前系统状态:\n");
if (get_system_info(&info) == 0) {
show_system_info(&info);
} else {
printf("获取系统信息失败: %s\n", strerror(errno));
return -1;
}
// 简短监控演示
printf("2. 简短监控演示 (10秒):\n");
real_time_monitoring(10, 3);
// 系统信息统计
printf("3. 系统信息统计:\n");
// 收集统计信息
unsigned long max_ram_used = 0, min_ram_used = (unsigned long)-1;
double max_load_1min = 0, min_load_1min = 999;
double total_ram_usage = 0, total_load_1min = 0;
int sample_count = 0;
printf("收集统计样本...\n");
for (int i = 0; i < 5; i++) {
if (get_system_info(&info) == 0) {
// 更新最大最小值
if (info.used_ram_mb > max_ram_used) max_ram_used = info.used_ram_mb;
if (info.used_ram_mb < min_ram_used) min_ram_used = info.used_ram_mb;
if (info.load_avg_1min > max_load_1min) max_load_1min = info.load_avg_1min;
if (info.load_avg_1min < min_load_1min) min_load_1min = info.load_avg_1min;
// 累加统计值
total_ram_usage += info.ram_usage_percent;
total_load_1min += info.load_avg_1min;
sample_count++;
}
sleep(1);
}
// 显示统计结果
if (sample_count > 0) {
printf("\n统计结果 (%d 个样本):\n", sample_count);
printf(" 内存使用范围: %lu MB - %lu MB\n", min_ram_used, max_ram_used);
printf(" 内存使用率范围: %.1f%% - %.1f%%\n",
min_ram_used * 100.0 / info.total_ram_mb,
max_ram_used * 100.0 / info.total_ram_mb);
printf(" 负载范围: %.2f - %.2f\n", min_load_1min, max_load_1min);
printf(" 平均内存使用率: %.1f%%\n", total_ram_usage / sample_count);
printf(" 平均1分钟负载: %.2f\n", total_load_1min / sample_count);
}
// 监控建议
printf("\n=== 系统监控建议 ===\n");
printf("1. 定期监控:\n");
printf(" - 每5分钟检查一次关键指标\n");
printf(" - 每小时生成详细报告\n");
printf(" - 每天汇总统计信息\n");
printf("\n2. 警报阈值:\n");
printf(" - 内存使用率 > 90%% 触发警告\n");
printf(" - 交换空间使用率 > 50%% 触发警告\n");
printf(" - 每CPU负载 > 1.5 触发警告\n");
printf(" - 进程数 > 1000 触发提醒\n");
printf("\n3. 性能优化:\n");
printf(" - 根据负载趋势调整资源配置\n");
printf(" - 及时清理内存泄漏进程\n");
printf(" - 优化高负载应用\n");
printf(" - 合理配置交换空间\n");
return 0;
}
int main() {
return demo_comprehensive_monitor();
}
sysfs/sysinfo 使用注意事项
系统要求:
- 内核版本: 支持sysfs的Linux内核(2.6+)
- 权限要求: 通常不需要特殊权限
- 挂载要求: sysfs必须正确挂载(通常在/sys)
sysfs特点:
- 虚拟文件系统: 不占用磁盘空间
- 动态更新: 实时反映内核状态
- 层次结构: 按照设备类型组织
- 只读属性: 大部分文件是只读的
sysinfo特点:
- 轻量级: 系统调用开销小
- 实时性: 提供当前系统状态
- 标准化: 跨平台兼容性好
- 信息全面: 涵盖主要系统指标
错误处理:
- ENOENT: 文件或目录不存在
- EACCES: 权限不足
- EINVAL: 参数无效
- ENOMEM: 内存不足
性能考虑:
- 缓存利用: 适当缓存频繁访问的信息
- 批量读取: 减少系统调用次数
- 异步处理: 避免阻塞主线程
- 增量更新: 只更新变化的信息
安全考虑:
- 权限检查: 验证访问权限
- 输入验证: 验证读取的数据
- 资源限制: 避免过度消耗系统资源
- 日志记录: 记录重要操作
最佳实践:
- 信息整合: 综合多个信息源
- 趋势分析: 关注指标变化趋势
- 警报机制: 及时发现异常情况
- 可视化展示: 直观显示监控结果
sysfs目录结构
主要目录:
/sys/
├── block/ # 块设备信息
├── bus/ # 总线信息
├── class/ # 设备类信息
├── dev/ # 设备信息
├── devices/ # 设备树
├── firmware/ # 固件信息
├── fs/ # 文件系统信息
└── kernel/ # 内核信息
sysinfo结构详解
struct 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; // 高端内存总量
unsigned long freehigh; // 可用高端内存
unsigned int mem_unit; // 内存单位
char _f[20-2*sizeof(__kernel_ulong_t)-sizeof(__u32)]; // 填充
};
常见使用场景
1. 系统监控:
// 实时监控系统资源使用情况
struct sysinfo si;
sysinfo(&si);
double ram_usage = (si.totalram - si.freeram) * 100.0 / si.totalram;
2. 性能分析:
// 分析系统负载和性能瓶颈
double load_per_cpu = si.loads[0] / (1 << SI_LOAD_SHIFT) / cpu_count;
3. 资源管理:
// 根据系统资源动态调整应用行为
if (si.freeram * si.mem_unit < MIN_MEMORY_THRESHOLD) {
// 内存不足,采取措施
}
4. 硬件信息查询:
// 通过sysfs查询硬件详细信息
char model[256];
read_sysfs_file("/sys/class/dmi/id/product_name", model, sizeof(model));
总结
sysfs
和 sysinfo
是Linux系统中重要的系统信息访问接口:
sysfs特点:
- 结构化信息: 提供详细的硬件和内核对象信息
- 动态更新: 实时反映系统状态变化
- 标准化接口: 统一的文件系统访问方式
- 丰富内容: 涵盖各类系统组件信息
sysinfo特点:
- 快速访问: 高效获取系统整体统计信息
- 标准API: 跨平台兼容的系统调用
- 全面指标: 包含内存、负载、进程等关键信息
- 实时监控: 适合构建监控和告警系统
通过合理使用这两个接口,可以构建功能强大的系统监控和管理工具,为系统运维和性能优化提供有力支持。在实际应用中,需要注意错误处理、性能优化和安全考虑等方面的问题。