Rust从入门到实战系列一百九十三:多线程和多所有权

在第十五章中,通过使用智能指针 Rc 来创建引用计数的值,以便拥有多所有者。让我们在这也这么
做看看会发生什么。将示例 16-14 中的 Mutex 封装进 Rc 中并在将所有权移入线程之前克隆了
Rc。
文件名: src∕main.rs
use std::rc::Rc;
use std::sync::Mutex;
use std::thread;
fn main() {
let counter = Rc::new(Mutex::new(0));
let mut handles = vec![];
for _ in 0…10 {
let counter = Rc::clone(&counter);
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-14: 尝试使用 Rc 来允许多个线程拥有 Mutex
再一次编译并⋯出现了不同的错误!编译器真是教会了我们很多!
$ cargo run
Compiling shared-state v0.1.0 (file:///projects/shared-state)
error[E0277]: Rc<Mutex<i32>> cannot be sent between threads safely
–> src/main.rs:11:22
|
11 | let handle = thread::spawn(move || {
| ____________^^^^^^^^^^^^^-
| | |
| | Rc<Mutex<i32>> cannot be sent between threads safely
12 | | let mut num = counter.lock().unwrap();
13 | |
14 | | *num += 1;
15 | | });
| |
- within this [closure@src/main.rs:11:36: 15:10]
|
= help: within [closure@src/main.rs:11:36: 15:10], the trait Send is not implemented for Rc<Mutex<i32>>
= note: required because it appears within the type [closure@src/main.rs:11:36: 15:10]
note: required by a bound in spawn
For more information about this error, try rustc --explain E0277.
error: could not compile shared-state due to previous error
哇哦,错误信息太长不看!这里是一些需要注意的重要部分:第一行错误表明 ‘ std:: rc :: Rc<std::sync::Mutex>‘ cannot be sent between threads safely。
编译器也告诉了我们原因 the trait bound ‘Send‘ is not satisfied。下一部分会讲到 Send:这是确保所
使用的类型可以用于并发环境的 trait 之一。
不幸的是,Rc 并不能安全的在线程间共享。当 Rc 管理引用计数时,它必须在每一个 clone 调用
时增加计数,并在每一个克隆被丢弃时减少计数。Rc 并没有使用任何并发原语,来确保改变计数的操
作不会被其他线程打断。在计数出错时可能会导致诡异的 bug,比如可能会造成内存泄漏,或在使用结束
之前就丢弃一个值。我们所需要的是一个完全类似 Rc,又以一种线程安全的方式改变引用计数的类型。

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值