Skip to content

Commit 3fc08c0

Browse files
committed
rust练习 代码
1 parent 153ca6d commit 3fc08c0

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

_posts/2025-07-29-rust-cpu-rate.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
---
2+
title: rust练习 cpu多线程计算
3+
---
4+
5+
```rust
6+
7+
use chrono::Local;
8+
use clap::Parser;
9+
use rand::Rng;
10+
use std::thread;
11+
use std::time::{Duration, Instant};
12+
use sysinfo::System;
13+
14+
#[derive(Parser, Debug, Clone)]
15+
#[command(version, about, long_about = None)]
16+
struct Args {
17+
#[arg(long, help = "使用的线程数", default_value_t = 2)]
18+
thread_count: u32,
19+
20+
#[arg(long, default_value_t = 50, help = "每个线程执行计算的时间比例",
21+
value_parser = clap::value_parser!(u32).range(1..100)
22+
)]
23+
thread_percent: u32,
24+
25+
#[arg(long, default_value_t = 30, help = "CPU总的最大的一分钟负载, 达到后, 程序睡眠. 此值为 (htop_load_average_1分钟 / CPU核数 * 100)",
26+
value_parser = clap::value_parser!(u32).range(1..100)
27+
)]
28+
max_load_average_percent: u32,
29+
30+
#[arg(long, action=clap::ArgAction::SetTrue)]
31+
verbose: bool,
32+
}
33+
34+
fn run_task(tid: u32, args: Args) {
35+
let sys = System::new_all();
36+
let cpu_nb = sys.cpus().len();
37+
38+
let max_load_avg = args.max_load_average_percent as f64 / 100f64 * cpu_nb as f64;
39+
40+
println!(
41+
"[{:?}]启动线程: {tid}, CPU: {cpu_nb}, 最大负载: {max_load_avg:.2}(={}%x{})",
42+
Local::now(),
43+
args.max_load_average_percent,
44+
cpu_nb,
45+
);
46+
47+
let mut rng = rand::rng();
48+
49+
loop {
50+
//
51+
let run_interval = rng.random_range(5..10) as f64;
52+
let run_sec = run_interval * args.thread_percent as f64 / 100f64;
53+
let sleep_sec = run_interval - run_sec;
54+
55+
let run_du = Duration::from_secs_f64(run_sec);
56+
let sleep_du = Duration::from_secs_f64(sleep_sec);
57+
58+
if args.verbose {
59+
println!(
60+
"[{:?}]线程{tid} 执行计算: {run_du:?}, 睡{sleep_du:?}",
61+
Local::now()
62+
);
63+
}
64+
65+
let now = Instant::now();
66+
let mut sum: i64 = 0;
67+
loop {
68+
if now.elapsed() > run_du {
69+
break;
70+
}
71+
72+
sum = sum.wrapping_add(1);
73+
}
74+
75+
if args.verbose {
76+
println!(
77+
"[{:?}]线程{tid} 执行睡眠: {run_du:?}, 睡{sleep_du:?}",
78+
Local::now()
79+
);
80+
}
81+
thread::sleep(sleep_du);
82+
83+
loop {
84+
let load_avg = System::load_average();
85+
if load_avg.one < max_load_avg {
86+
break;
87+
}
88+
let sleep_du = Duration::from_secs(rng.random_range(5..10));
89+
90+
if args.verbose {
91+
println!(
92+
"[{:?}]线程{tid} 检测到超过最大负载 {} > {}, 睡眠 {:?}",
93+
Local::now(),
94+
load_avg.one,
95+
max_load_avg,
96+
sleep_du
97+
);
98+
}
99+
100+
thread::sleep(sleep_du);
101+
}
102+
}
103+
}
104+
105+
fn main() {
106+
let args = Args::parse();
107+
108+
println!(
109+
"启动线程 {}, 每线程计算时间占比: {}%, 最高负载: {}%, 打印日志: {}",
110+
args.thread_count, args.thread_percent, args.max_load_average_percent, args.verbose
111+
);
112+
113+
for tid in 0..args.thread_count {
114+
let args = args.clone();
115+
thread::spawn(move || {
116+
run_task(tid, args);
117+
});
118+
}
119+
120+
let sys = System::new_all();
121+
let cpu_nb = sys.cpus().len();
122+
123+
124+
let sleep_du = Duration::from_millis(5000);
125+
loop {
126+
thread::sleep(sleep_du);
127+
128+
let avg = System::load_average();
129+
130+
println!(
131+
"[{:?}]当前负载: {:.2}%, {:?}",
132+
Local::now(),
133+
avg.one / cpu_nb as f64 * 100f64,
134+
avg,
135+
);
136+
}
137+
}
138+
139+
140+
```

0 commit comments

Comments
 (0)