gpt4 book ai didi

rust - 使用人造丝并行迭代器时的同步和发送特征

转载 作者:行者123 更新时间:2023-12-03 11:25:59 24 4
gpt4 key购买 nike

我有一个特征集合,我希望能够为 map 中的每个项目调用特征的可变方法。

目前我按顺序执行此操作,我的收藏如下所示:

use std::cell::RefCell;
use std::collections::*;
use std::rc::Rc;

trait Trait {
fn foo_mut(&mut self);
}

fn main() {
let mut items: HashMap<i32, Rc<RefCell<dyn Trait>>> = HashMap::new();
// I have a separate data structure that holds Week<RefCell<dyn Trait>>

for item in items.values_mut() {
item.borrow_mut().foo_mut();
}
}

我现在想并行调用 trait 方法,所以我首先将我的数据结构更改为:

use std::collections::*;
use std::sync::{Arc, RwLock};

fn main() {
let mut items: HashMap<i32, Arc<RwLock<dyn Trait>>> = HashMap::new();

for item in items.values_mut() {
item.write().unwrap().foo_mut();
}
}

然后我遇到了 rayon ,我尝试使用它的并行迭代器,但是下面的代码引发了一个错误:

items.par_iter_mut().for_each(|(id, item)| item.write().unwrap().foo_mut());
error[E0599]: no method named `par_iter_mut` found for struct `std::collections::HashMap<i32, std::sync::Arc<std::sync::RwLock<dyn Trait>>>` in the current scope
--> src/main.rs:12:11
|
12 | items.par_iter_mut().for_each(|(id, item)| item.write().unwrap().foo_mut());
| ^^^^^^^^^^^^ help: there is an associated function with a similar name: `iter_mut`
|
= note: the method `par_iter_mut` exists but the following trait bounds were not satisfied:
`&mut std::collections::HashMap<i32, std::sync::Arc<std::sync::RwLock<dyn Trait>>>: rayon::iter::IntoParallelIterator`
which is required by `std::collections::HashMap<i32, std::sync::Arc<std::sync::RwLock<dyn Trait>>>: rayon::iter::IntoParallelRefMutIterator`

我查看了for_each文档,它要求Self::ItemSend,闭包为Send + Sync,现在据我所见,Arc 已经是 Send + Sync,但可以通过将这两个特征添加到我的代码中来修复代码,例如:

let mut items: HashMap<i32, Arc<RwLock<dyn Trait + Send + Sync>>> = HashMap::new();

为什么这是必要的?

最佳答案

Send 的实现和 Sync对于 Arc<T>看起来像 this :

impl<T> Send for Arc<T>
where
T: Send + Sync + ?Sized,

impl<T> Sync for Arc<T>
where
T: Send + Sync + ?Sized,

这意味着Arc<T>只有SendSync如果T也是(见here解释原因)。

同样,RwLock<T>只有SendSync如果T is :

impl<T: ?Sized + Send> Send for RwLock<T>
impl<T: ?Sized + Send + Sync> Sync for RwLock<T>

一起,这意味着 Arc<RwLock<dyn Trait>>只会是 SendSync如果dyn Trait也是。如果写起来很麻烦 dyn Trait + Send + Sync你知道你永远不想实现 Trait对于任何类型都不是 SendSync ,然后您可以将这些作为边界添加到特征中:

trait Trait: Send + Sync {
fn foo_mut(&mut self);
}

然后你的原始代码是Arc<RwLock<dyn Trait>>将与 rayon 一起工作.

关于rust - 使用人造丝并行迭代器时的同步和发送特征,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62374960/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com