当值的所有者可以在另一个线程更改它时读取它时,Rust如何防止数据争用?

问题描述 投票:0回答:1

Rust书在References and borrowing中陈述以下内容

当我们有一个不可变的引用时,我们也不能有一个可变的引用。不可变引用的用户不希望值突然从它们下面改变!但是,多个不可变引用是可以的,因为没有人只是读取数据有能力影响其他人读取数据。

但是所有者可以读取数据,而另一个线程通过可变借用来改变价值,对吗?难道我们不会再遇到常见的问题,或者我在哪里误解了潜在的概念?

concurrency rust
1个回答
3
投票

所有者可以读取数据,而另一个线程通过可变借入更改值,对吧?

这是不正确的,甚至不涉及多个线程也无关紧要。

您可以在以下示例中看到自己(Playground)。这是一个字符串值x被修改,同时保留对相同值y的引用:

let mut x = "123".to_string();
let y = &mut x;

x.push_str("456");

println!("y = {}", y);

这无法编译:

error[E0499]: cannot borrow `x` as mutable more than once at a time
 --> src/main.rs:5:5
  |
3 |     let y = &mut x;
  |             ------ first mutable borrow occurs here
4 |     
5 |     x.push_str("456");
  |     ^ second mutable borrow occurs here
6 | 
7 |     println!("y = {}", y);
  |                        - first borrow later used here

当我们试图调用push_str这个接收&mut self的方法时,假设一个新的可变参考值被建立在现场。由于x已经在该范围内借用,这是非法的。

现在,您甚至可以考虑重新分配而不是调用期望&mut self的方法。还有,机会很大:

let mut x = "123".to_string();
let y = &mut x;

x = "321".to_string();

println!("y = {}", y);
error[E0506]: cannot assign to `x` because it is borrowed
 --> src/main.rs:5:5
  |
3 |     let y = &mut x;
  |             ------ borrow of `x` occurs here
4 |     
5 |     x = "321".to_string();
  |     ^ assignment to borrowed `x` occurs here
6 | 
7 |     println!("y = {}", y);
  |                        - borrow later used here

借来的价值也不能重新分配。

总而言之,价值的所有者仍然受到任何借款的限制。如果价值是不可改变的借用,所有者也可以拥有不可变的访问权限,但只要借款到位,就不能将价值写入或移动。当值被可变地借用时,在删除该引用之前,所有者不能对该值执行任何操作。

© www.soinside.com 2019 - 2024. All rights reserved.