我想学习如何用 Rust 编写这段 Go 代码,这里的 go 代码可供参考: https: //go.dev/play/p/j9osOG5xs1R
它基本上启动 100 个线程,每个线程循环 1000 次,每次迭代休眠 1 毫秒,并且还会增加一些共享状态。
由于它休眠 1 毫秒,因此应该在 1 秒内完成。
在我的 Go 版本中,我实际上创建了 100 个线程,并且按预期在大约 1 秒内完成。
我的 Rust 代码目前只有 10 个线程,需要 10 秒才能完成。
我一定做错了什么,有什么提高性能的建议吗?
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::Duration;
fn main() {
let counter = Arc::new(Mutex::new(0));
let mut handles = vec![];
use std::time::Instant;
let now = Instant::now();
for _ in 0..10 {
let counter = Arc::clone(&counter);
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
for _ in 0..1000 {
thread::sleep(Duration::from_millis(1));
*num += 1;
}
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!("Result: {}", *counter.lock().unwrap());
let elapsed = now.elapsed();
println!("Elapsed: {:.2?}", elapsed);
}
Run Code Online (Sandbox Code Playgroud)
我什至还在发布模式下构建了该程序:
cargo build --release
./target/release/spawner
Run Code Online (Sandbox Code Playgroud)
由于某种原因,只有 10 个线程需要 10 秒以上......
每个线程counter在其运行的整个 1 秒内都会锁定,从而阻止所有线程取得任何进展。这导致它们顺序运行而不是并行运行。
如果缩小锁的范围,那么它们将每毫秒抓取并释放互斥锁,从而相互解除阻塞并允许程序在预期的 1 秒内完成。
let handle = thread::spawn(move || {
for _ in 0..1000 {
thread::sleep(Duration::from_millis(1));
let mut num = counter.lock().unwrap();
*num += 1;
}
});
Run Code Online (Sandbox Code Playgroud)
输出:
Result: 10000
Elapsed: 1.09s
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
917 次 |
| 最近记录: |