对于 Rust 中的多个可变引用,同步如何成为问题?
Posted
技术标签:
【中文标题】对于 Rust 中的多个可变引用,同步如何成为问题?【英文标题】:How is synchronizing is a problem for multiple mutable references in Rust? 【发布时间】:2021-12-20 13:59:27 【问题描述】:我在阅读 Rust 文档第 4 节时看到了这样的代码:
let mut s = String::from("hello");
let r1 = &mut s;
let r2 = &mut s;
println!(", ", r1, r2);
所以文档说你不能在 Rust 中拥有多个可变引用。好的,有道理,但文档说如果你可以使用会发生三种行为,其中之一是:
没有用于同步访问数据的机制。
是否需要同步机制?我的意思是我们已经使用了指向堆的指针或指向堆的另一个指针。
我的意思是在这个图中,假设我们有 s2
和 s3
作为对 s1
的可变引用。
s1
已经有一个指向堆的指针,所以 s2
和 s3
有指向 s1 的指针。当我们更改s2
或s3
时,堆中的内存不会发生变化吗?
let mut s1 = String::from("Hello");
let s2 = &mut s1;
s2.push_str(", world");
在这里,s1
指向的堆中的内存已更改,因此s3
已经指向该内存,所以它不是已经同步了吗?
我有一个问题,为什么我们不应该使用多个可变引用。我只是假设我们可以。 Rust 说没有同步访问数据的机制。我的问题是,我们已经从每个引用中获得了指向堆的指针,所以当我们更改堆中的值时,它们都会同步,因为它们不是值,它们只是指向堆的指针,并且堆中的值被更改?
【问题讨论】:
指针不提供同步。 这是一个规则,没有什么了。 一些很好的理由:manishearth.github.io/blog/2015/05/17/… 【参考方案1】:想象一下,如果允许以下情况:
let mut maybe_five = Some(5);
let mut zero = 0;
// first mutable borrow
let ref_five = &mut maybe_five;
// second mutable borrow
// number_ref is a reference inside maybe_five's Some
let number_ref = match &mut maybe_five
Some(ref mut five) => five,
_ => &mut zero,
;
// invalidate number_ref by making the value it points to invalid
*ref_five = None;
// now we write into a None???
*number_ref = 10;
我们将能够在安全生锈的情况下执行各种未定义的行为。
【讨论】:
不会说其他允许这样做的语言? 不,我明白为什么我们不应该有多个可变引用。但我只是想知道我提到的行为:同步。我的问题是,为什么我们需要一种机制来同步可变引用如果我们可以在 Rust 中拥有该功能。 @DoğukanAkkaya 该功能确实存在于 rust 中:doc.rust-lang.org/std/sync/struct.Mutex.html 同步不是默认的原因是它在计算上并不便宜。例如,互斥锁会锁定。而且还因为如果我们没有多个可变引用,则没有必要。 这就是我真正要问的。同步不是引用的默认行为吗?当堆中的值发生变化时,所有的引用都会同步,因为它们只是指针,而不是值。我的意思是x
指向 0x00 地址,y
指向 0x00 地址,z
拥有该值。当z
更改x
和y
时已经同步了对吗?我只是不明白为什么同步是使用多个可变引用的问题之一。我了解这种方法的其他问题,但不是那样。以上是关于对于 Rust 中的多个可变引用,同步如何成为问题?的主要内容,如果未能解决你的问题,请参考以下文章