the*_*ian 3 concurrency multithreading rust
我想更好地理解以下Rust代码背后的语义:
use std::thread;
fn main() {
let immutable = "I am not mutable";
let mut mutable = "I am mutable";
let handle1 = thread::spawn(move || {
println!("Thread 1 says: {}", immutable);
});
let handle2 = thread::spawn(move || {
println!("Thread 2 says: {}", immutable);
});
let handle3 = thread::spawn(move || {
println!("Thread 3 says: {}", mutable);
mutable = "go away";
});
let handle4 = thread::spawn(move || {
println!("Thread 4 says: {}", mutable);
});
handle1.join().unwrap();
handle2.join().unwrap();
}
Run Code Online (Sandbox Code Playgroud)
我不明白为什么要编译此代码。我mutable在多个线程之间共享了该变量,甚至对其进行了突变。内存在幕后到底发生了什么?我们是否在静态内存中使多个指针指向同一字符串?我们是否在内存中放置了两个不同的静态字符串?我可以让两个线程从同一个不可变项中读取数据,这一事实并不令我感到惊讶,但是让两个线程从一个可变变量中读取数据确实令我惊讶。
请注意,即使线程3在4之前运行,线程4也不反映线程3在其println!语句中设置的更新字符串。最后,由于我没有通过using &immutable,这是否意味着该值正在“移动”到每个线程中,而不是实际的内存地址中?
我在多个线程之间共享了相同的可变变量,甚至对其进行了突变。
不,您已将对同一静态字符串的引用复制到多个线程中。该引用指向一个不变的静态字符串,该字符串不能被突变。只读引用是Copy,因此您可以将它们移动到多个闭包中。
内存在幕后到底发生了什么?
字符串切片实际上是指向内存中字符串开头以及长度的指针。您的变量mutable和immutable仅包含这两部分信息,并且只有这两部分是可变的mutable。变量指向的实际字符串是不可变的。当将变量“移动”到闭包中时,实际上是将它们复制,因为&str是Copy。复制的唯一信息是指针和长度,而不是实际的字符串数据。您最终会获得指向同一只读内存的多个指针,这不允许任何数据争用并且符合Rust的内存安全规则。
另外,请注意,即使线程3在4、4之前运行,也不会反映线程3在其println中设置的更新字符串!声明。
您仅修改指针的副本和长度。在线程3中,它mutable成为闭包局部的一个单独变量,您只需对其进行修改。
最后,由于我没有通过using
&immutable,这是否意味着该值正在“移动”到每个线程中,而不是实际的内存地址中?
变量immutable的类型为&'static str,因此它已经是引用;&immutable将是对参考的参考。
| 归档时间: |
|
| 查看次数: |
370 次 |
| 最近记录: |