| Crates.io | cpu_load |
| lib.rs | cpu_load |
| version | 0.1.8 |
| created_at | 2025-12-28 21:18:13.634719+00 |
| updated_at | 2026-01-09 04:33:00.359474+00 |
| description | Real-time CPU load monitoring with intelligent core selection / 实时 CPU 负载监控与智能核心选择 |
| homepage | https://github.com/js0-site/rust/tree/main/cpu_load |
| repository | https://github.com/js0-site/rust.git |
| max_upload_size | |
| id | 2009400 |
| size | 82,010 |
cpu_load is high-performance Rust library for real-time CPU load monitoring and intelligent core selection, built on the compio async ecosystem.
Traditional CPU load APIs (like sysinfo) require waiting ~200ms between calls to get accurate readings. This library solves that problem by running background sampling tasks, allowing instant access to pre-collected metrics without blocking.
The library continuously samples CPU usage in background tasks, maintaining up-to-date load metrics for global CPU and individual cores. Through atomic operations and lock-free data structures, it delivers high-performance monitoring suitable for concurrent applications.
CPU_LOAD for convenient accessuse cpu_load::CPU_LOAD;
// Global CPU load (0-100)
let global = CPU_LOAD.global();
println!("Global: {global}%");
// Get idlest core for task assignment
let core = CPU_LOAD.idlest();
println!("Idlest core: {core}");
// Iterate all core loads
for (i, load) in CPU_LOAD.into_iter().enumerate() {
println!("Core {i}: {load}%");
}
use cpu_load::CpuLoad;
// Default 1s sampling interval
let monitor = CpuLoad::new();
// Specific core load
if let Some(load) = monitor.core(0) {
println!("Core 0: {load}%");
}
// Core count
println!("Cores: {}", monitor.len());
use std::time::Duration;
use cpu_load::CpuLoad;
// Custom 500ms sampling interval
let monitor = CpuLoad::init(Duration::from_millis(500));
use cpu_load::CPU_LOAD;
// Collect to vector
let loads: Vec<u8> = CPU_LOAD.into_iter().collect();
// Filter high-load cores
let high: Vec<usize> = CPU_LOAD
.into_iter()
.enumerate()
.filter(|(_, load)| *load > 80)
.map(|(i, _)| i)
.collect();
// Calculate average
let avg = CPU_LOAD.into_iter().map(|x| x as u32).sum::<u32>() / CPU_LOAD.len() as u32;
Global static instance with default 1s sampling interval. Lazily initialized on first access.
pub static CPU_LOAD: CpuLoad;
Main structure for CPU load monitoring.
| Method | Description |
|---|---|
new() -> Self |
Create monitor with default 1s interval |
init(interval: Duration) -> Self |
Create monitor with custom sampling interval |
global(&self) -> u8 |
Current global CPU load (0-100) |
core(&self, idx: usize) -> Option<u8> |
Specific core load (0-100) |
len(&self) -> usize |
Number of CPU cores |
is_empty(&self) -> bool |
Check if no cores |
idlest(&self) -> usize |
Index of idlest CPU core |
Implements Default trait, equivalent to CpuLoad::new().
Iterator over core loads, implements Iterator<Item = u8> and ExactSizeIterator.
impl<'a> IntoIterator for &'a CpuLoad {
type Item = u8;
type IntoIter = CpuLoadIter<'a>;
}
graph TD
A[CpuLoad::new/init] --> B[Create Instance]
B --> C[Spawn Background Task]
B --> D[Return CpuLoad]
C --> E[Initial Delay 100ms]
E --> F[Sample CPU Metrics]
F --> G[Sleep Interval]
G --> H{Stop Signal?}
H -->|No| F
H -->|Yes| I[Free Memory via defer]
J[idlest Call] --> K{cursor >= n?}
K -->|No| L[Return rank at cursor]
K -->|Yes| M{CAS sorting?}
M -->|Fail| N[Spin Wait]
N --> L
M -->|Success| O[Sort by Load]
O --> P[Reset cursor]
P --> Q[Return rank 0]
Lock-free Design: All shared state uses atomic operations. The sorting flag acts as lightweight spinlock only during rank array updates.
Lazy Evaluation: Core sorting occurs only when cursor exhausts rank array, amortizing sort cost across multiple idlest() calls.
Memory Safety: Raw pointer with AtomicPtr enables Arc-free design. Background task owns memory via defer, ensuring cleanup on drop.
Zero Allocation: Pre-allocated Box<[AtomicU8]> for core loads and Box<[UnsafeCell<usize>]> for rank array. No runtime heap allocation.
| Component | Purpose |
|---|---|
| Rust 2024 | Modern language features |
| compio | Async runtime (io-uring/IOCP) |
| sysinfo | Cross-platform system info |
| static_init | Lazy static initialization |
| defer-lite | RAII cleanup guarantee |
compio leverages platform-specific I/O primitives:
cpu_load/
├── src/
│ ├── lib.rs # Core implementation, CpuLoad struct, CPU_LOAD static
│ └── iter.rs # CpuLoadIter iterator
├── tests/
│ └── main.rs # Integration tests
├── readme/
│ ├── en.md # English documentation
│ └── zh.md # Chinese documentation
└── Cargo.toml
CPU load monitoring traces back to early Unix systems where load average measured system demand—average processes in run queue over 1, 5, and 15 minutes.
The mid-2000s shift from single-core to multi-core processors created need for per-core tracking. This library builds on that evolution with real-time per-core metrics.
The lazy round-robin algorithm draws inspiration from distributed system load balancers. Rather than maintaining continuously sorted lists (computationally expensive), it uses on-demand sorting triggered by access patterns. This approach mirrors the "power of two choices" algorithm used in modern load balancers like Nginx and HAProxy.
Lock-free programming became essential with multi-core CPUs. The CAS (Compare-And-Swap) operation used in idlest() is fundamental to concurrent data structures, first implemented in hardware by IBM System 370 in 1970.
Fun fact: The term "load average" was coined by the TENEX operating system in the early 1970s at BBN Technologies. TENEX later influenced Unix development, and the concept persists in modern systems via /proc/loadavg on Linux.
This project is an open-source component of js0.site ⋅ Refactoring the Internet Plan.
We are redefining the development paradigm of the Internet in a componentized way. Welcome to follow us:
cpu_load 是高性能 Rust 库,用于实时 CPU 负载监控和智能核心选择,基于 compio 异步生态系统构建。
传统 CPU 负载 API(如 sysinfo)每次调用需等待约 200ms 才能获取准确读数。本库通过后台采样任务解决此问题,允许即时访问预采集的指标,无需阻塞等待。
库在后台任务中持续采样 CPU 使用率,维护全局 CPU 和各核心的最新负载指标。通过原子操作和无锁数据结构,为并发应用提供高性能监控。
CPU_LOAD 便捷访问use cpu_load::CPU_LOAD;
// 全局 CPU 负载 (0-100)
let global = CPU_LOAD.global();
println!("全局: {global}%");
// 获取最空闲核心用于任务分配
let core = CPU_LOAD.idlest();
println!("最空闲核心: {core}");
// 遍历所有核心负载
for (i, load) in CPU_LOAD.into_iter().enumerate() {
println!("核心 {i}: {load}%");
}
use cpu_load::CpuLoad;
// 默认 1 秒采样间隔
let monitor = CpuLoad::new();
// 指定核心负载
if let Some(load) = monitor.core(0) {
println!("核心 0: {load}%");
}
// 核心数
println!("核心数: {}", monitor.len());
use std::time::Duration;
use cpu_load::CpuLoad;
// 自定义采样间隔 500ms
let monitor = CpuLoad::init(Duration::from_millis(500));
use cpu_load::CPU_LOAD;
// 收集到向量
let loads: Vec<u8> = CPU_LOAD.into_iter().collect();
// 过滤高负载核心
let high: Vec<usize> = CPU_LOAD
.into_iter()
.enumerate()
.filter(|(_, load)| *load > 80)
.map(|(i, _)| i)
.collect();
// 计算平均值
let avg = CPU_LOAD.into_iter().map(|x| x as u32).sum::<u32>() / CPU_LOAD.len() as u32;
全局静态实例,默认 1 秒采样间隔。首次访问时惰性初始化。
pub static CPU_LOAD: CpuLoad;
CPU 负载监控主结构体。
| 方法 | 描述 |
|---|---|
new() -> Self |
使用默认 1 秒间隔创建监控器 |
init(interval: Duration) -> Self |
使用自定义采样间隔创建监控器 |
global(&self) -> u8 |
当前全局 CPU 负载 (0-100) |
core(&self, idx: usize) -> Option<u8> |
指定核心负载 (0-100) |
len(&self) -> usize |
CPU 核心数 |
is_empty(&self) -> bool |
检查是否无核心 |
idlest(&self) -> usize |
最空闲 CPU 核心索引 |
实现 Default trait,等同于 CpuLoad::new()。
核心负载迭代器,实现 Iterator<Item = u8> 和 ExactSizeIterator。
impl<'a> IntoIterator for &'a CpuLoad {
type Item = u8;
type IntoIter = CpuLoadIter<'a>;
}
graph TD
A[CpuLoad::new/init] --> B[创建实例]
B --> C[启动后台任务]
B --> D[返回 CpuLoad]
C --> E[初始延迟 100ms]
E --> F[采样 CPU 指标]
F --> G[休眠间隔]
G --> H{停止信号?}
H -->|否| F
H -->|是| I[通过 defer 释放内存]
J[idlest 调用] --> K{cursor >= n?}
K -->|否| L[返回 cursor 处的 rank]
K -->|是| M{CAS sorting?}
M -->|失败| N[自旋等待]
N --> L
M -->|成功| O[按负载排序]
O --> P[重置 cursor]
P --> Q[返回 rank 0]
无锁设计:所有共享状态使用原子操作。sorting 标志仅在更新 rank 数组时作为轻量级自旋锁。
惰性求值:仅当 cursor 耗尽 rank 数组时才排序,将排序成本分摊到多次 idlest() 调用。
内存安全:裸指针配合 AtomicPtr 实现无 Arc 设计。后台任务通过 defer 拥有内存,确保 drop 时清理。
零分配:预分配 Box<[AtomicU8]> 存储核心负载,Box<[UnsafeCell<usize>]> 存储 rank 数组。运行时无堆分配。
| 组件 | 用途 |
|---|---|
| Rust 2024 | 现代语言特性 |
| compio | 异步运行时 (io-uring/IOCP) |
| sysinfo | 跨平台系统信息 |
| static_init | 惰性静态初始化 |
| defer-lite | RAII 清理保证 |
compio 利用平台特定 I/O 原语:
cpu_load/
├── src/
│ ├── lib.rs # 核心实现、CpuLoad 结构体、CPU_LOAD 静态变量
│ └── iter.rs # CpuLoadIter 迭代器
├── tests/
│ └── main.rs # 集成测试
├── readme/
│ ├── en.md # 英文文档
│ └── zh.md # 中文文档
└── Cargo.toml
CPU 负载监控可追溯到早期 Unix 系统,load average 衡量系统需求——1、5、15 分钟内运行队列中的平均进程数。
2000 年代中期从单核到多核处理器的转变产生了对每核心跟踪的需求。本库在此演进基础上提供实时每核心指标。
惰性轮询算法灵感来自分布式系统负载均衡器。它不维护连续排序列表(计算成本高),而是根据访问模式按需排序。这种方法类似于 Nginx 和 HAProxy 等现代负载均衡器使用的"二选一"算法。
无锁编程随多核 CPU 变得至关重要。idlest() 中使用的 CAS(比较并交换)操作是并发数据结构的基础,最早由 IBM System 370 在 1970 年实现于硬件。
趣闻:"load average" 术语由 BBN Technologies 在 1970 年代初的 TENEX 操作系统中创造。TENEX 后来影响了 Unix 开发,该概念通过 Linux 的 /proc/loadavg 延续至今。
本项目为 js0.site ⋅ 重构互联网计划 的开源组件。
我们正在以组件化的方式重新定义互联网的开发范式,欢迎关注: