rust - 如何在 Rust 中使用 Mutex 创建临界区?
问题描述
我是 Rust 的新手。我应该使用 aMutex
和 anArc
在print_lots
函数中创建一个关键部分,以阻止竞争条件的发生。有任何想法吗?
fn main() {
let num_of_threads = 4;
let mut array_of_threads = vec![];
for id in 0..num_of_threads {
array_of_threads.push(std::thread::spawn(move || print_lots(id)));
}
for t in array_of_threads {
t.join().expect("Thread join failure");
}
}
fn print_lots(id: u32) {
println!("Begin [{}]", id);
for _i in 0..100 {
print!("{} ", id);
}
println!("\nEnd [{}]", id);
}
解决方案
Mutex
Rust 中的锁的工作方式可能与您可能习惯的其他语言中的锁工作方式不同。Rust 不是独立于值跟踪锁,而是Mutex
拥有数据并防止在没有首先获得锁的情况下访问它,这是在编译时强制执行的。
您收到的警告是因为您已锁定Mutex
,但随后对该值没有执行任何操作。警告在那里,因为这几乎可以肯定是一个错误。
fn main() {
let foo = Mutex::new(0);
// It's often best to just unwrap and panic if the lock is poisoned
if let Ok(mut lock) = foo.lock() {
*lock = 2;
// The mutex is unlocked automatically when lock goes out of scope here
}
println!("{:?}", foo); // Mutex { data: 2 }
}
我猜你真正的问题是你想同步打印语句,以便不同线程的输出不会混合。
一种方法是获取一个StdOut
实际上在内部使用锁的锁,并提供类似的 API Mutex
:
fn print_lots(id: u32) {
let stdout = io::stdout();
println!("Begin [{}]", id);
let mut handle = stdout.lock();
for _i in 0..100 {
write!(&mut handle, "{} ", id).unwrap();
}
println!("\nEnd [{}]", id);
// handle is dropped here, unlocking stdout
}
在您的简化示例中,在每个线程中创建一个长寿命锁会适得其反,因为每个线程都会阻塞其他线程,结果是顺序的而不是并发的。如果您的实际代码有更多工作要做,这可能仍然有意义。
推荐阅读
- c# - 乘以 @Html.DisplayFor(modelItem => item.gheimatkol) 值
- c# - C# 创建带有转义的 HTML 行
- reporting-services - 将 RDL 报告上传到 SSRS,不包括用户凭据
- ruby - Ruby Net::OpenTimeout 调用“puts”,奇怪的堆栈跟踪。多线程应用
- latex - 在 Lyx 中启用 shell-escape 时删除警告
- django - 有没有办法总是按 django-tables2 中的特定列对表进行排序?
- amazon-ec2 - Ubuntu 上的 Hyperledger composer CLI 安装问题
- sql - 如何在两个表之间执行数学运算
- reactjs - Puppeteer - 如何点击内部元素
- r - 在函数下方绘制垂直表面