如何从Rust的生成线程中非可变地借用(可变)Vec?

时间:2019-12-19 22:45:42

标签: multithreading rust borrowing

Rust相当陌生,在理解此线程/所有权问题时遇到了很多麻烦。解决方案和/或解释将不胜感激。

因此,在我的主线程中,我有一个很大的Vec<i32>,这是可变的,因为主线程偶尔会重新分配它:

let mut lots_of_ints: Vec<i32> = LOTS_OF_INPUTS.to_vec();

我需要基于此向量重复进行工作。每次迭代都是独立的,只需要读取向量,而无需对其进行突变。所以我想将工作分成多个线程。为此,我编写了一个小的调度函数:

fn dispatch(lots_of_ints: &Vec<i32>, start: usize, stop: usize) -> thread::JoinHandle<Vec<i32>> {
    thread::spawn(|| {
        let mut new_section = Vec::with_capacity(TOTAL_ITERATIONS / THREAD_COUNT);

        for iteration in start..stop {
            new_section.push(do_work(&lots_of_ints, iteration)))
        }

        new_section
    })
}

然后我这样称呼它:

let thread_handles = (0..THREAD_COUNT).map(|i| {
    let start = i * TOTAL_ITERATIONS / THREAD_COUNT;
    let stop = (i + 1) * TOTAL_ITERATIONS / THREAD_COUNT;

    dispatch(&lots_of_ints, start, stop)
});

lots_of_ints = thread_handles
    .map(|handle| { handle.join().unwrap() })
    .flat_map(|new_section| { new_section })
    .collect::<Vec<i32>>();

对我的新手Rust来说,这似乎应该可行。我让每个线程借用一个对大向量的非可变引用,然后我的主线程使用join等待每个生成的线程完成其工作,并在完成后将它们重新缝合在一起。

但是,如果可以,我当然不会在这里。我收到此编译错误:

error[E0621]: explicit lifetime required in the type of `lots_of_ints`
  --> src/main.rs:83:5
   |
82 | fn dispatch(lots_of_ints: &Vec<i32>, start: usize, stop: usize) -> thread::JoinHandle<Vec<i32>> {
   |                     --------- help: add explicit lifetime `'static` to the type of `lots_of_ints`: `&'static std::vec::Vec<i32>`
83 |     thread::spawn(|| {
   |     ^^^^^^^^^^^^^ lifetime `'static` required

error: aborting due to previous error

我曾尝试将static'static添加到不同的地方,但是最终陷入了编译错误的陷阱,我不清楚为什么我需要弄乱它的生命周期变量。据我了解,如果我借用参考资料,所有权不会转移。它应该留在我的主线程中,并由我的派生线程引用。

无论如何,显然我缺少了一些东西。有见识吗?

0 个答案:

没有答案