Rust 为什么';t人造丝需要电弧<_>;?
在第465页,您可以找到代码和解释(我添加了重点)Rust 为什么';t人造丝需要电弧<_>;?,rust,reference-counting,lifetime-scoping,Rust,Reference Counting,Lifetime Scoping,在第465页,您可以找到代码和解释(我添加了重点) 在“重写为使用人造丝”一节中,您可以看到它接受&GigabyteMap而不是Arc。但是他们没有解释这是如何工作的。为什么人造丝不需要Arc?Rayon如何接受直接引用?Rayon可以保证迭代器不会超过当前堆栈帧,这与我在第一个代码示例中假设的是thread::spawn不同。具体来说,引擎盖下的par_iter使用了类似人造丝的功能,它允许生成一个工作单元,该工作单元“连接”到堆栈,并在堆栈结束前连接 由于Rayon可以保证(从用户的角度来看
在“重写为使用人造丝”一节中,您可以看到它接受
&GigabyteMap
而不是Arc
。但是他们没有解释这是如何工作的。为什么人造丝不需要Arc
?Rayon如何接受直接引用?Rayon可以保证迭代器不会超过当前堆栈帧,这与我在第一个代码示例中假设的是thread::spawn
不同。具体来说,引擎盖下的par_iter
使用了类似人造丝的功能,它允许生成一个工作单元,该工作单元“连接”到堆栈,并在堆栈结束前连接
由于Rayon可以保证(从用户的角度来看,通过生命周期边界)在调用par_iter
的函数退出之前加入任务/线程,因此它可以提供比标准库的thread::spawn
更符合人体工程学的API
Rayon在中对此进行了扩展。您的问题似乎可以通过的答案得到回答。如果没有,请回答您的问题以解释差异。否则,我们可以将此问题标记为已回答。当芯部生锈时,人造丝如何才能提供此保证?人造丝是否在内部使用Arc?std可以保证这一点,但目前没有这样的功能(留给像人造丝和横梁这样的库)。Rayon保证线程在作用域函数退出之前连接(无论是由于解绕还是正常返回);由于
mem::forget
的原因,这无法在返回类型中使用基于RAII的API来完成。
use std::sync::Arc;
fn process_files_in_parallel(filenames: Vec<String>,
glossary: Arc<GigabyteMap>)
-> io::Result<()>
{
...
for worklist in worklists {
// This call to .clone() only clones the Arc and bumps the
// reference count. It does not clone the GigabyteMap.
let glossary_for_child = glossary.clone();
thread_handles.push(
spawn(move || process_files(worklist, &glossary_for_child))
);
}
...
}
extern crate rayon;
use rayon::prelude::*;
fn process_files_in_parallel(filenames: Vec<String>, glossary: &GigabyteMap)
-> io::Result<()>
{
filenames.par_iter()
.map(|filename| process_file(filename, glossary))
.reduce_with(|r1, r2| {
if r1.is_err() { r1 } else { r2 }
})
.unwrap_or(Ok(()))
}