你能为线程指定一个非静态生命周期吗?

3

这是我的问题的一个玩具示例:

use std::sync::{Arc, Mutex};

fn operate_in_chunks(vec: &mut Vec<f32>) {
    let chunk_size = 10;
    let mutex_vec: Arc<Mutex<&mut Vec<f32>>> = Arc::new(Mutex::new(vec));

    let handles = Vec::new();

    for chunk in 0..vec.len() / chunk_size {
        handles.push(std::thread::spawn(move || {
            operate(mutex_vec, chunk);
        }));
    }

    for i in 0..handles.len() {
        handles[i].join().unwrap();
    }
}

fn operate(mutex_vec: Arc<Mutex<&mut Vec<f32>>>, chunk: usize) {}

我想在传入的结构体上进行一些工作,将其分成多个线程,然后在返回之前将它们全部合并在一起。

我收到的错误信息如下:

error[E0621]: explicit lifetime required in the type of `vec`
  --> src/lib.rs:10:22
   |
3  | fn operate_in_chunks(vec: &mut Vec<f32>) {
   |                           ------------- help: add explicit lifetime `'static` to the type of `vec`: `&'static mut std::vec::Vec<f32>`
...
10 |         handles.push(std::thread::spawn(move || {
   |                      ^^^^^^^^^^^^^^^^^^ lifetime `'static` required


我理解它的投诉内容: 如果线程可能拥有'static'生命周期,并且引用了'vec',那么'vec'必须具有'static'生命周期。然而,在我的使用情况下,理论上应该是可行的:我想要确保线程不具有'static'生命周期,因为它们在函数返回之前都已经加入,此时我不需要在'vec'上使用'static' 生命周期。
Rust是否有一种表达方式 - 将线程的生命周期与'vec'的生命周期统一起来 - 或者所有线程无论如何都是静态的?

1
Crossbeam具有作用域线程的概念,允许您使用非静态生命周期。 - Alex Huszagh
1
作用域线程在大约两年前就从 Rust 中删除了,因此在 Rust 标准库中没有办法使用非静态生命周期:https://www.reddit.com/r/rust/comments/57c5uq/what_happened_to_threadscoped/ - Alex Huszagh
如果 operate_in_chunks 方法在调用 join() 之前发生 panic,会导致引用过早被丢弃。 - SOFe
1
哇,这个线程和其链接的线程真的将其描绘成一部史诗般的(并且持续不断的)传说。如果你想将其作为答案发布,我认为这是可能最接近答案的东西了。 - brundolf
1个回答

4

Rust曾经允许作用域线程,允许传递任何数据的非静态生命周期。但是,该API被发现不安全并于大约两年前被移除。幸运的是,crossbeam这个crate使用不同的API实现了作用域线程,使您可以安全地使用此功能。crossbeam文档中的示例在此处:

let array = [1, 2, 3];

crossbeam::scope(|scope| {
    for i in &array {
        scope.spawn(move || {
            println!("element: {}", i);
        });
    }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接