chunks_exact_mut线程生存时间



下面的代码产生了有趣的结果:

use std::thread;
fn main() {
let mut handles = Vec::new();
let mut v = vec![1, 2, 3, 4];

for x in v.chunks_exact_mut(2) {
let handle = thread::spawn(move || {
println!("Here's a vector: {:?}", x);
});

handles.push(handle);
}
for h in handles { h.join().unwrap(); }
}
error[E0597]: `v` does not live long enough
--> src/main.rs:7:14
|
7  |     for x in v.chunks_exact_mut(2) {
|              ^^^^^^^^^^^^^^^^^^^^^
|              |
|              borrowed value does not live long enough
|              argument requires that `v` is borrowed for `'static`
...
16 | }
| - `v` dropped here while still borrowed

为什么"分块"v会改变生存期?没有对v进行"分块"处理,代码可以正确执行。为什么现在会抛出错误呢?

这里的问题是thread::spawn完全与其他线程解耦,因为当main已经完成时,线程可能会继续运行。

x是对main中的一个变量的引用,不能保证main的生存时间比线程长。

我认为你真正想要的是一个像rayon这样的线程助手库,因为它们已经在内部解决了这些问题:

use rayon::prelude::*;
fn main() {
let mut v = vec![1, 2, 3, 4];
v.par_chunks_exact_mut(2).for_each(|x: &mut [i32]| {
let thread_id = std::thread::current().id();
println!("{:?}: Here's a vector: {:?}", thread_id, x);
});
}
ThreadId(5): Here's a vector: [1, 2]
ThreadId(2): Here's a vector: [3, 4]

不带" chunking"v,你在Vec<i32>上迭代。该迭代器产生i32类型的项,因此,没有引用,没有生命周期,满足thread::spawn()的要求(特别是'static的要求)。

然而,chunks_exact_mut()是在片上定义的,并在&mut [T]上提供迭代器,因此确实有引用。由于此引用引用的v存在于main()中,因此它不是'static,因此不起作用。

如果迭代&v而不是v,可以观察到同样的问题,因为迭代器给出的是&i32s (playground):

error[E0597]: `v` does not live long enough
--> src/main.rs:7:14
|
7  |     for x in &v {
|              ^^
|              |
|              borrowed value does not live long enough
|              argument requires that `v` is borrowed for `'static`
...
16 | }
| - `v` dropped here while still borrowed

除此之外,我建议使用@Finomnis建议的rayon

最新更新