Rust 中并行分段素筛的生命周期错误

Life-time error in Parallel segmented-prime-sieve in Rust

我试图在 Rust 中使并行成为一个主要的筛子,但 Rust 编译器并没有给我一个参数 true_block.

的生命周期错误

数据竞争无关紧要,因为素数是如何定义的。

错误是:

    error[E0621]: explicit lifetime required in the type of `true_block`
  --> src/sieve.rs:65:22
   |
50 |     true_block: &mut Vec<bool>,
   |                 -------------- help: add explicit lifetime `'static` to the type of `true_block`: `&'static mut Vec<bool>`
...
65 |         handles.push(thread::spawn(move || {
   |                      ^^^^^^^^^^^^^ lifetime `'static` required

密码是:

fn extend_helper(
    primes: &Vec<usize>,
    true_block: &mut Vec<bool>,
    segment_min: usize,
    segment_len: usize,
) {
    let mut handles: Vec<thread::JoinHandle<()>> = vec![];
    let arc_primes = Arc::new(true_block);

    let segment_min = Arc::new(segment_min);
    let segment_len = Arc::new(segment_len);
    for prime in primes {
        let prime = Arc::new(prime.clone());
        let segment_min = Arc::clone(&segment_min);
        let segment_len = Arc::clone(&segment_len);
        let shared = Arc::clone(&arc_primes);

        handles.push(thread::spawn(move || {
            let tmp = smallest_multiple_of_n_geq_m(*prime, *segment_min) - *segment_min;
            for j in (tmp..*segment_len).step_by(*prime) {
                shared[j] = false;
            }
        }));
    }

    for handle in handles {
        handle.join().unwrap();
    }
}

生命周期问题与 true_block 有关,它是传递给函数的可变引用。它的生命周期与调用函数一样长,但是因为你正在生成一个线程,线程 可以 存活到函数结束之后(编译器不能确定).由于不知道线程将存活多长时间,因此传递给它的数据的生命周期必须是 'static,这意味着它会一直存在到程序结束。

要解决此问题,您可以使用 .to_owned() 克隆存储在 Arc 中的数组,这将解决生命周期问题。然后,您需要在加入线程后将数组日期从 Arc 中复制出来,并将其写回 true_block 引用。但是也不可能改变 Arc,它只持有对值的不可变引用。你需要为 arc_primes 使用 Arc<Mutex<_>> 然后你可以用 shared.lock().unwrap()[j] = false; 或更安全的东西

来改变 shared