当我将工作委派给线程时,我经常会有一段数据比所有线程的寿命都长,例如numbers
在以下示例中:
use std::thread;
fn main() {
let numbers = vec![1, 2, 3];
let thread_a = thread::spawn(|| println!("{}", numbers.len()));
let thread_b = thread::spawn(|| println!("{}", numbers.len()));
thread_a.join().unwrap();
thread_b.join().unwrap();
}
它没有在任何地方进行修改,并且因为join
s,保证线程使用它完成。然而,Rust 的借用检查器无法判断:
error[E0373]: closure may outlive the current function, but it borrows `numbers`, which is owned by the current function
--> src/main.rs:6:34
|
6 | let thread_a = thread::spawn(|| println!("{}", numbers.len()));
| ^^ ------- `numbers` is borrowed here
| |
| may outlive borrowed value `numbers`
|
note: function requires argument type to outlive `'static`
--> src/main.rs:6:20
|
6 | let thread_a = thread::spawn(|| println!("{}", numbers.len()));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: to force the closure to take ownership of `numbers` (and any other referenced variables), use the `move` keyword
|
6 | let thread_a = thread::spawn(move || println!("{}", numbers.len()));
| ^^^^^^^
到目前为止我见过的解决方案都涉及克隆数据片段(或克隆一个Arc
的数据)。但是,是否可以在不进行任何克隆的情况下做到这一点?
您可能有错误的想法:克隆Arc
只是增加引用计数器并复制指针;它不执行任何额外的分配。当然,创建Arc
涉及分配,但是您已经在分配以构造Vec
,因此额外的固定大小分配不太可能造成损害。
如果你们都really需要的是长度,你可以计算出来outside线程的闭包并将其存储在变量中; Ausize
跨越线程边界没有问题。
问题是编译器无法从使用中推断出join()
给定的线程被绑定到有限的生命周期......它甚至不尝试。
在 Rust 1.0 之前,有was a thread::scoped
构造函数允许您传入非'static
引用,但由于内存安全问题,必须不稳定。看如何将对堆栈变量的引用传递给线程? https://stackoverflow.com/q/32750829/155423的替代方案。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)