Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 为什么';t人造丝需要电弧<_>;?_Rust_Reference Counting_Lifetime Scoping - Fatal编程技术网

Rust 为什么';t人造丝需要电弧<_>;?

Rust 为什么';t人造丝需要电弧<_>;?,rust,reference-counting,lifetime-scoping,Rust,Reference Counting,Lifetime Scoping,在第465页,您可以找到代码和解释(我添加了重点) 在“重写为使用人造丝”一节中,您可以看到它接受&GigabyteMap而不是Arc。但是他们没有解释这是如何工作的。为什么人造丝不需要Arc?Rayon如何接受直接引用?Rayon可以保证迭代器不会超过当前堆栈帧,这与我在第一个代码示例中假设的是thread::spawn不同。具体来说,引擎盖下的par_iter使用了类似人造丝的功能,它允许生成一个工作单元,该工作单元“连接”到堆栈,并在堆栈结束前连接 由于Rayon可以保证(从用户的角度来看

在第465页,您可以找到代码和解释(我添加了重点)


在“重写为使用人造丝”一节中,您可以看到它接受
&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(()))
}