我正在尝试使并行成为 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();
}
}
生命周期问题在于'static
它是传递给函数的可变引用。 它的生存期仅与调用函数的时间一样长,但由于您正在生成一个线程,因此该线程可能会存活到函数末尾之后(编译器无法确定)。 由于不知道线程将存活多长时间,因此传递给它的数据的生存期必须.to_owned()
,这意味着它将一直存在到程序结束。
要解决此问题,您可以使用Arc
来克隆存储在Arc
中的数组,这将解决生命周期问题。 然后,您需要在加入线程后将数组日期从Arc
中复制出来,并将其写回true_block引用。 但是也不可能改变一个Arc<Mutex<_>>
,它只持有对值的不可变引用。 您需要使用arc_primes
进行shared
,然后您可以使用CC_12或更安全的东西shared.lock().unwrap()[j] = false;
变异