use std::thread;
fn main() {
let s = String::from("Hello, Rust!");
let handle = thread::spawn(move || {
println!("The string in the new thread: {}", s);
});
handle.join().unwrap();
}
所有权转移或借用处理
- 所有权转移:在上述代码中,使用
move
关键字将 s
的所有权转移到闭包中。move
关键字告诉编译器闭包需要获取捕获变量的所有权。这样,新线程就拥有了 s
的所有权,可以在其作用域内使用它。
- 避免借用:如果不使用
move
,闭包会尝试借用 s
。但是主线程在闭包执行期间可能会结束,这就会导致悬垂引用。通过 move
,我们确保闭包拥有 s
的所有权,避免了这种情况。
可能遇到的陷阱
- 闭包执行时间过长:如果闭包中的操作执行时间过长,可能会导致主线程等待
join
操作的时间过长,影响程序的响应性。
- 数据竞争:如果多个线程同时访问和修改同一个数据,会导致数据竞争。在这个例子中,因为只有新线程使用
s
,并且是只读操作,所以不存在数据竞争。但如果多个线程都要修改 s
,就需要使用 Mutex
或 RwLock
等同步原语来保护数据。
- 所有权管理不当:如果不小心在主线程中继续使用已经被
move
到闭包中的变量,编译器会报错。例如:
use std::thread;
fn main() {
let s = String::from("Hello, Rust!");
let handle = thread::spawn(move || {
println!("The string in the new thread: {}", s);
});
// 下面这行代码会报错,因为 `s` 的所有权已经被转移到闭包中
// println!("Trying to use s in main thread: {}", s);
handle.join().unwrap();
}