系统信息
开篇故事
想象你要检查电脑的健康状况。传统方式是:打开各种工具 → 查看 CPU → 查看内存 → 查看进程。sysinfo 库就像是:系统仪表盘——一个库获取所有系统信息。
本章适合谁
如果你需要在 Rust 程序中获取系统信息(CPU、内存、进程),本章适合你。sysinfo 是跨平台系统监控的标准库。
你会学到什么
完成本章后,你可以:
- 获取系统信息
- 获取内存使用情况
- 获取进程列表
- 监控特定进程
- 获取 CPU 信息
前置要求
- 结构体 - 结构体基础
- 错误处理 - 错误处理基础
依赖安装
运行以下命令安装所需依赖:
cargo add sysinfo
cargo add bigdecimal
第一个例子
获取系统信息:
use sysinfo::{System, SystemExt};
fn main() {
// 创建系统实例
let mut system = System::new_all();
// 刷新所有信息
system.refresh_all();
// 获取可用内存
println!("可用内存:{} MB", system.available_memory() / 1024 / 1024);
// 获取系统信息
println!("操作系统:{:?}", System::name());
println!("系统版本:{:?}", System::os_version());
println!("CPU 架构:{:?}", System::cpu_arch());
}
完整示例: sysinfo_sample.rs
原理解析
sysinfo 特性
sysinfo 是系统信息库:
- ✅ 跨平台支持
- ✅ 获取系统信息
- ✅ 获取进程信息
- ✅ 实时监控
创建系统实例
使用 System::new_all():
use sysinfo::{System, SystemExt};
let mut system = System::new_all();
使用 System::new():
// 只创建,不刷新
let mut system = System::new();
// 手动刷新
system.refresh_memory();
system.refresh_processes();
获取系统信息
获取操作系统信息:
use sysinfo::System;
println!("操作系统:{:?}", System::name());
println!("系统版本:{:?}", System::os_version());
println!("CPU 架构:{:?}", System::cpu_arch());
println!("发行版:{:?}", System::distribution_id());
println!("内核版本:{:?}", System::kernel_version());
获取内存信息
获取内存使用情况:
use sysinfo::{System, SystemExt};
let mut system = System::new_all();
println!("总内存:{} MB", system.total_memory() / 1024 / 1024);
println!("可用内存:{} MB", system.available_memory() / 1024 / 1024);
println!("已用内存:{} MB", system.used_memory() / 1024 / 1024);
获取进程信息
获取所有进程:
use sysinfo::{System, SystemExt, Pid};
let mut system = System::new_all();
for (pid, process) in system.processes() {
println!("进程 ID: {:?}", pid);
println!("进程名:{}", process.name());
println!("CPU 使用:{}%", process.cpu_usage());
println!("内存:{} MB", process.memory() / 1024 / 1024);
}
监控特定进程
获取特定进程:
use sysinfo::{System, SystemExt, Pid, ProcessExt};
let mut system = System::new_all();
let pid = std::process::id();
if let Some(process) = system.process(Pid::from_u32(pid as usize)) {
println!("当前进程:");
println!(" 名称:{}", process.name());
println!(" CPU: {}%", process.cpu_usage());
println!(" 内存:{} MB", process.memory() / 1024 / 1024);
println!(" 启动时间:{}", process.start_time());
println!(" 运行时间:{:?}", process.run_time());
}
常见错误
错误 1: 忘记刷新
let mut system = System::new();
println!("{}", system.available_memory());
// ❌ 没有刷新,数据可能过时
修复方法:
let mut system = System::new_all(); // ✅ 创建时刷新
// 或
system.refresh_memory(); // ✅ 手动刷新
错误 2: PID 类型错误
let pid = std::process::id(); // u32
system.process(pid); // ❌ 需要 Pid 类型
修复方法:
use sysinfo::Pid;
let pid = std::process::id();
system.process(Pid::from_u32(pid as usize)); // ✅ 转换类型
错误 3: 忘记导入 trait
use sysinfo::System;
let mut system = System::new_all();
system.refresh_all(); // ❌ 需要导入 SystemExt
修复方法:
use sysinfo::{System, SystemExt}; // ✅ 导入 trait
动手练习
练习 1: 获取系统信息
use sysinfo::{System, SystemExt};
fn main() {
let mut system = System::new_all();
// TODO: 打印操作系统名称
// TODO: 打印系统版本
// TODO: 打印 CPU 架构
}
点击查看答案
println!("操作系统:{:?}", System::name());
println!("系统版本:{:?}", System::os_version());
println!("CPU 架构:{:?}", System::cpu_arch());
练习 2: 获取内存信息
use sysinfo::{System, SystemExt};
fn main() {
let mut system = System::new_all();
// TODO: 打印总内存
// TODO: 打印可用内存
// TODO: 打印已用内存
}
点击查看答案
println!("总内存:{} MB", system.total_memory() / 1024 / 1024);
println!("可用内存:{} MB", system.available_memory() / 1024 / 1024);
println!("已用内存:{} MB", system.used_memory() / 1024 / 1024);
练习 3: 监控当前进程
use sysinfo::{System, SystemExt, Pid};
fn main() {
let mut system = System::new_all();
let pid = std::process::id();
// TODO: 获取当前进程
// TODO: 打印进程信息(名称、CPU、内存)
}
点击查看答案
if let Some(process) = system.process(Pid::from_u32(pid as usize)) {
println!("名称:{}", process.name());
println!("CPU: {}%", process.cpu_usage());
println!("内存:{} MB", process.memory() / 1024 / 1024);
}
故障排查 (FAQ)
Q: 为什么获取的内存信息不准确?
A:
- 需要调用 refresh_all() 或 refresh_memory()
- 数据是快照,会随时间变化
Q: 如何持续监控?
A:
loop {
system.refresh_processes();
println!("CPU: {}%", process.cpu_usage());
std::thread::sleep(Duration::from_secs(1));
}
Q: sysinfo 支持哪些平台?
A:
- Linux
- macOS
- Windows
- FreeBSD
知识扩展
CPU 信息
use sysinfo::{System, SystemExt};
let mut system = System::new_all();
println!("CPU 核心数:{}", system.cpus().len());
for cpu in system.cpus() {
println!("CPU {}: {}%", cpu.name(), cpu.cpu_usage());
}
磁盘信息
use sysinfo::{System, SystemExt};
let mut system = System::new_all();
for disk in system.disks() {
println!("磁盘:{:?}", disk.name());
println!("总空间:{} GB", disk.total_space() / 1024 / 1024 / 1024);
println!("可用空间:{} GB", disk.available_space() / 1024 / 1024 / 1024);
}
网络接口
use sysinfo::{System, SystemExt};
let mut system = System::new_all();
for (interface_name, network) in system.networks() {
println!("接口:{}", interface_name);
println!("接收:{} bytes", network.total_received());
println!("发送:{} bytes", network.total_transmitted());
}
小结
核心要点:
- System: 系统信息
- SystemExt: 系统扩展 trait
- 进程监控: 获取进程信息
- 跨平台: 支持多平台
关键术语:
- System: 系统
- Process: 进程
- PID: 进程 ID
- Memory: 内存
术语表
| English | 中文 |
|---|---|
| System | 系统 |
| Process | 进程 |
| PID | 进程 ID |
| Memory | 内存 |
| CPU | 中央处理器 |
知识检查
快速测验(答案在下方):
-
System::new_all()做了什么? -
如何获取特定进程的信息?
-
refresh_all()和new_all()的区别?
点击查看答案与解析
- 创建 System 实例并刷新所有信息(CPU、内存、进程等)
- 使用
system.process(Pid::from_u32(pid)) new_all()= 创建 + 刷新,refresh_all()= 仅刷新已有实例
关键理解: sysinfo 提供跨平台的系统和进程信息。
继续学习
相关章节:
返回: 高级进阶
完整示例: sysinfo_sample.rs