在使用 par_iter() 处理大型数组时,我无法更新到不同的可变数组

I am unable to update to different mutable arrays while processing a big array using par_iter()

提问人:Padma 提问时间:2/22/2023 更新时间:2/22/2023 访问量:55

问:

要处理的大量结构数组和两个不同的可变数组应保存这些值。

我使用了par_iter,但出现以下错误:

fn par_calculate_depreciation_for_assets(assets_to_depreciate: &Vec<Depreciation>) -> Result<(), Ferror> {
    let mut acc_dep = 0;
    let mut errors: Vec<String> = vec![];
    let mut assets_record : Vec<AssetRecord> = Vec::new();

    assets_to_depreciate.par_iter().for_each( |item| {
        
        let result = calculate_monthly_depreciation(item);
        
        if result.is_err()
            {
                errors.push(item.asset_code.clone());
         
            }
        else
            {
                let (asset, depreciated_asset) = result.unwrap();
                build_csv_struct(item, &mut assets_record, asset);
            } 
    });
    
    append_to_csv(assets_record);
    dbg!("Errors {:?} unprocessed", errors);
    Ok(())
}
error[E0596]: cannot borrow `errors` as mutable, as it is a captured variable in a `Fn` closure
  --> src/services/csv_services/dep_for_all_assets_in_csv_copy.rs:69:17
   |
69 |                 errors.push(item.asset_code.clone());
   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
阵 列 可变 人造丝

评论


答:

1赞 Jonas Fassbender 2/22/2023 #1

您当前看到的错误是,您的闭包实现了您传递给并行迭代器上的调用的 Fn 特征,这是 Rust 不允许的。errorsfor_each

但是,您当前的实现存在一个更根本的问题。有一个竞争条件。如果两个线程同时尝试将元素添加到 ?您必须确保访问是互斥的。我真的可以推荐阅读 Rust 书的共享状态并发部分:https://doc.rust-lang.org/book/ch16-03-shared-state.htmlerrorserrors

下面是一个最小的示例,它通过包装在互斥体中来修复您的错误和争用条件:errors

use rayon::prelude::*;

use std::sync::Mutex;

fn par_calculate_depreciation_for_assets(assets_to_depreciate: &Vec<u8>) -> Vec<String> {
    let errors: Mutex<Vec<String>> = Mutex::new(vec![]);

    assets_to_depreciate.par_iter().for_each(|item| {
        let mut errors = errors.lock().unwrap();
        errors.push(item.to_string());
    });

    errors.into_inner().unwrap()
}

fn main() {
    let errors = par_calculate_depreciation_for_assets(&vec![0, 1, 2, 3]);

    assert_eq!(
        errors,
        vec![
            "0".to_owned(),
            "1".to_owned(),
            "2".to_owned(),
            "3".to_owned()
        ]
    )
}

操场。

评论

0赞 Padma 7/4/2023
谢谢,这奏效了。对于延迟回复,我们深表歉意。