sysinfo系统调用及示例

sysfs 和 sysinfo 函数详解

  1. 函数介绍

sysfs

sysfs 是Linux内核提供的虚拟文件系统,用于导出内核对象的信息到用户空间。它以文件和目录的形式呈现系统硬件、驱动程序、设备状态等信息,是现代Linux系统管理和监控的重要接口。

sysinfo

sysinfo 是Linux系统调用,用于获取系统的整体统计信息,包括内存使用情况、系统负载、运行时间等。它提供了一种编程方式来获取系统状态信息。

  1. 函数原型

sysfs

1
2
3
4
5
6
7
#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

1
2
3
4
#include <sys/sysinfo.h>

int sysinfo(struct sysinfo *info);

  1. 功能

sysfs

  • 提供内核对象的结构化信息访问

  • 导出硬件设备、驱动程序、总线等信息

  • 支持动态查询设备状态和属性

sysinfo

  • 获取系统内存使用统计

  • 查询系统负载和运行时间

  • 获取进程和用户统计信息

  1. 参数

sysfs

  • *const char name: 总线或设备名称

  • *const char devpath: 设备路径

  • *const char attr_name: 属性名称

sysinfo

  • *struct sysinfo info: 指向sysinfo结构的指针
  1. 返回值

sysfs

  • 成功: 返回相应的句柄或字符串

  • 失败: 返回NULL,并设置errno

sysinfo

  • 成功: 返回0

  • 失败: 返回-1,并设置errno

  1. 相似函数,或关联函数

sysfs相关:

  • opendir/readdir: 目录遍历

  • open/read: 文件读取

  • /sys/: sysfs挂载点

sysinfo相关:

  • getloadavg: 获取系统负载平均值

  • getrusage: 获取资源使用情况

  • /proc/: procfs文件系统

  1. 示例代码

示例1:基础sysinfo使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
#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&#91;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(&current_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&#91;0] / (1 << SI_LOAD_SHIFT));
printf(" 5分钟平均负载: %.2f\n", (double)si.loads&#91;1] / (1 << SI_LOAD_SHIFT));
printf(" 15分钟平均负载: %.2f\n", (double)si.loads&#91;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:内存监控工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
#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&#91;32];
strftime(time_str, sizeof(time_str), "%H:%M:%S", localtime(&now));

printf("&#91;%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:系统负载监控

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#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&#91;0] / (1 << SI_LOAD_SHIFT);
stats->load_avg_5min = (double)si.loads&#91;1] / (1 << SI_LOAD_SHIFT);
stats->load_avg_15min = (double)si.loads&#91;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&#91;64];
char current_time_str&#91;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&#91;32];
strftime(time_str, sizeof(time_str), "%H:%M:%S", localtime(&now));

printf("&#91;%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使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#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&#91;bytes_read] = '\0';

// 移除末尾的换行符
if (bytes_read > 0 && buffer&#91;bytes_read - 1] == '\n') {
buffer&#91;bytes_read - 1] = '\0';
}

close(fd);
return 0;
}

/**
* 显示CPU信息
*/
void show_cpu_info() {
DIR *dir;
struct dirent *entry;
char path&#91;256];
char buffer&#91;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&#91;3] >= '0' && entry->d_name&#91;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&#91;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&#91;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&#91;0] != '.') {
char path&#91;256];
char buffer&#91;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&#91;] = {
{"/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&#91;i].path; i++) {
char buffer&#91;256];
if (read_sysfs_file(attributes&#91;i].path, buffer, sizeof(buffer)) == 0) {
printf("%s: %s\n", attributes&#91;i].description, buffer);
} else {
printf("%s: 无法读取 (%s)\n", attributes&#91;i].description, strerror(errno));
}
}

return 0;
}

int main() {
return demo_sysfs_basic();
}

示例5:综合系统监控工具

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
#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&#91;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&#91;0] / (1 << SI_LOAD_SHIFT);
info->load_avg_5min = (double)si.loads&#91;1] / (1 << SI_LOAD_SHIFT);
info->load_avg_15min = (double)si.loads&#91;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&#91;64];
char boot_time_str&#91;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("&#91;第 %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+)

data-ad-format="fluid" data-ad-layout-key="-7k+ex-4a-9w+4a">

权限要求: 通常不需要特殊权限

挂载要求: sysfs必须正确挂载(通常在/sys)

sysfs特点:

虚拟文件系统: 不占用磁盘空间

动态更新: 实时反映内核状态

层次结构: 按照设备类型组织

只读属性: 大部分文件是只读的

sysinfo特点:

轻量级: 系统调用开销小

实时性: 提供当前系统状态

标准化: 跨平台兼容性好

信息全面: 涵盖主要系统指标

错误处理:

ENOENT: 文件或目录不存在

EACCES: 权限不足

EINVAL: 参数无效

ENOMEM: 内存不足

性能考虑:

缓存利用: 适当缓存频繁访问的信息

批量读取: 减少系统调用次数

异步处理: 避免阻塞主线程

增量更新: 只更新变化的信息

安全考虑:

权限检查: 验证访问权限

输入验证: 验证读取的数据

资源限制: 避免过度消耗系统资源

日志记录: 记录重要操作

最佳实践:

信息整合: 综合多个信息源

趋势分析: 关注指标变化趋势

警报机制: 及时发现异常情况

可视化展示: 直观显示监控结果

sysfs目录结构

主要目录:

1
2
3
4
5
6
7
8
9
10
/sys/
├── block/ # 块设备信息
├── bus/ # 总线信息
├── class/ # 设备类信息
├── dev/ # 设备信息
├── devices/ # 设备树
├── firmware/ # 固件信息
├── fs/ # 文件系统信息
└── kernel/ # 内核信息

sysinfo结构详解

struct sysinfo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct sysinfo {
long uptime; // 系统运行时间(秒)
unsigned long loads&#91;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&#91;20-2*sizeof(__kernel_ulong_t)-sizeof(__u32)]; // 填充
};

常见使用场景

1. 系统监控:

1
2
3
4
5
// 实时监控系统资源使用情况
struct sysinfo si;
sysinfo(&si);
double ram_usage = (si.totalram - si.freeram) * 100.0 / si.totalram;

2. 性能分析:

1
2
3
// 分析系统负载和性能瓶颈
double load_per_cpu = si.loads&#91;0] / (1 << SI_LOAD_SHIFT) / cpu_count;

3. 资源管理:

1
2
3
4
5
// 根据系统资源动态调整应用行为
if (si.freeram * si.mem_unit < MIN_MEMORY_THRESHOLD) {
// 内存不足,采取措施
}

4. 硬件信息查询:

1
2
3
4
// 通过sysfs查询硬件详细信息
char model&#91;256];
read_sysfs_file("/sys/class/dmi/id/product_name", model, sizeof(model));

总结

sysfs 和 sysinfo 是Linux系统中重要的系统信息访问接口:

sysfs特点:

结构化信息: 提供详细的硬件和内核对象信息

动态更新: 实时反映系统状态变化

标准化接口: 统一的文件系统访问方式

丰富内容: 涵盖各类系统组件信息

sysinfo特点:

快速访问: 高效获取系统整体统计信息

标准API: 跨平台兼容的系统调用

全面指标: 包含内存、负载、进程等关键信息

实时监控: 适合构建监控和告警系统

通过合理使用这两个接口,可以构建功能强大的系统监控和管理工具,为系统运维和性能优化提供有力支持。在实际应用中,需要注意错误处理、性能优化和安全考虑等方面的问题。

data-ad-format="auto" data-full-width-responsive="true">