现在让我们尝试使用 Mutex 在多个线程间共享值。我们将启动十个线程,并在各个线程中对同一个
计数器值加一,这样计数器将从 0 变为 10。示例 16-13 中的例子会出现编译错误,而我们将通过这些错
误来学习如何使用 Mutex,以及 Rust 又是如何帮助我们正确使用的。
文件名: src∕main.rs
use std::sync::Mutex;
use std::thread;
fn main() {
let counter = Mutex::new(0);
let mut handles = vec![];
for _ in 0…10 {
let handle = thread::spawn(move || {
let mut num = counter.lock().unwrap();
*num += 1;
});
handles.push(handle);
}
for handle in handles {
handle.join().unwrap();
}
println!(“Result: {}”, *counter.lock().unwrap());
}
示例 16-13: 程序启动了 10 个线程,每个线程都通过 Mutex 来增加计数器的值
这里创建了一个 counter 变量来存放内含 i32 的 Mutex,类似示例 16-12 那样。接下来遍历 range
创建了 10 个线程。使用了 thread::spawn 并对所有线程使用了相同的闭包:他们每一个都将调用 lock方法来获取 Mutex 上的锁,接着将互斥器中的值加一。当一个线程结束执行,num 会离开闭包作用
域并释放锁,这样另一个线程就可以获取它了。
在主线程中,我们像示例 16-2 那样收集了所有的 join 句柄,调用它们的 join 方法来确保所有线程都会
结束。这时,主线程会获取锁并打印出程序的结果。
之前提示过这个例子不能编译,让我们看看为什么!
$ cargo run
Compiling shared-state v0.1.0 (file:///projects/shared-state)
error[E0382]: use of moved value: counter
–> src/main.rs:9:36
|
5 | let counter = Mutex::new(0);
| ------- move occurs because counter
has type Mutex<i32>
, which does not implement the Copy
trait
…
9 | let handle = thread::spawn(move || {
| ^^^^^^^ value moved into closure here, in previous iteration of loop
10 | let mut num = counter.lock().unwrap();
| ------- use occurs due to use in closure
For more information about this error, try rustc --explain E0382
.
error: could not compile shared-state
due to previous error
错误信息表明 counter 值在上一次循环中被移动了。所以 Rust 告诉我们不能将 counter 锁的所有权移
动到多个线程中。让我们通过一个第十五章讨论过的多所有权手段来修复这个编译错误。
Rust从入门到实战系列一百九十二:在线程间共享 Mutex<T>
最新推荐文章于 2024-07-26 11:18:19 发布