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
我试图在 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