Data structures 如何锁定Rust数据结构的内部?

Data structures 如何锁定Rust数据结构的内部?,data-structures,collections,concurrency,rust,Data Structures,Collections,Concurrency,Rust,我正在尝试实现一个集合,该集合将值存储在向量和hashmap中,这就是我目前所拥有的: pub struct CollectionWrapper { items: Vec<Item>, items_map: HashMap<ItemKey, Item>, } impl CollectionWrapper { pub fn new() -> Self { CollectionWrapper {

我正在尝试实现一个集合,该集合将值存储在向量和hashmap中,这就是我目前所拥有的:

pub struct CollectionWrapper {
    items:      Vec<Item>,
    items_map:  HashMap<ItemKey, Item>,
}

impl CollectionWrapper {
    pub fn new() -> Self {
        CollectionWrapper {
            items: Vec::new(),
            items_map: HashMap::new(),
        }
    }

    pub fn add(&mut self, item: Item) {
        let key = item.get_key();
        self.items.push(item.clone());
        self.items_map.insert(key, item.clone());
    }
}
我显然需要一把锁

我不知道我是否同意这种需要。只有当多个线程可以同时修改对象时,我才会引入锁。注意有两个条件:多线程和并发修改

如果您只有一个线程,那么Rust对一个项目的单个可变引用的强制执行将防止任何问题。同样,如果您有多个线程,并且在它们之间完全转移项目的所有权,则不需要任何锁定,因为只有一个线程可以对其进行变异

我要找的东西是:

try {
    lock.lock();
    // insert into both collections
} finally {
    lock.unlock();
}
try {
    lock.lock();
    // insert into both collections
} finally {
    lock.unlock();
}
如果您需要类似的东西,那么您可以创建一个
互斥体
——一个锁定单元类型的互斥体,它不占用任何空间:

use std::sync::Mutex;

struct Thing {
    lock: Mutex<()>,
    nums: Vec<i32>,
    names: Vec<String>,
}

impl Thing {
    fn new() -> Thing {
        Thing {
            lock: Mutex::new(()),
            nums: vec![],
            names: vec![],
        }
    }

    fn add(&mut self) {
        let _lock = self.lock.lock().unwrap();
        // Lock is held until the end of the block

        self.nums.push(42);
        self.names.push("The answer".to_string());
    }
}

fn main() {
    let mut thing = Thing::new();
    thing.add();
}

注意,<代码> MutExGueGue/COD>也实现了,并且允许它“看起来”像锁定类型。C++中的

有;它更复杂,因为它支持更新。非常感谢您的深入回答。但是,我不明白你所说的“通常最好将要锁定的项目包装起来。”是什么意思。非常感谢。这帮了大忙
use std::sync::Mutex;

struct Thing {
    nums: Vec<i32>,
    names: Vec<String>,
}

impl Thing {
    fn new() -> Thing {
        Thing {
            nums: vec![],
            names: vec![],
        }
    }

    fn add(&mut self) {
        self.nums.push(42);
        self.names.push("The answer".to_string());
    }
}

fn main() {
    let thing = Thing::new();
    let protected = Mutex::new(thing);
    let mut locked_thing = protected.lock().unwrap();
    locked_thing.add();
}