我想学习如何用Rust编写这个Go代码,go代码在这里供参考:https://go.dev/play/p/j9osOG5xs1R
它基本上启动100个线程,在每个线程中循环1000次,在每次迭代中休眠1毫秒,并增加一些共享状态。
由于它的睡眠时间为1毫秒,它应该在1秒内完成。
在我的Go版本中,我实际上创建了100个线程,它按照预期在1秒内完成。
我的生锈代码目前只有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);
}
我甚至在发布模式下构建了这个程序:
cargo build --release
./target/release/spawner
出于某种原因,只有10个线程需要超过10秒.
发布于 2022-09-15 22:05:10
每个线程在它运行的整个1秒内锁定counter
,阻止所有线程取得任何进展。这导致它们按顺序运行,而不是并行运行。
如果你缩小锁的范围,那么他们会每毫秒抓取并释放互斥物,互相解锁,并允许程序在预期的1秒内完成。
let handle = thread::spawn(move || {
for _ in 0..1000 {
thread::sleep(Duration::from_millis(1));
let mut num = counter.lock().unwrap();
*num += 1;
}
});
输出:
Result: 10000
Elapsed: 1.09s
https://stackoverflow.com/questions/73737825
复制相似问题