rust 如何共享数据而不锁定整个数据?

m3eecexj  于 2022-11-12  发布在  其他
关注(0)|答案(1)|浏览(132)

请考虑以下情况。

let mut map = HashMap::new();
map.insert(2,5);    
thread::scope(|s|{
    s.spawn(|_|{
        map.insert(1,5);
    });
    s.spawn(|_|{
        let d = map.get(&2).unwrap();
    });
}).unwrap();

这段代码无法编译,因为我们在h1中可变地借用了变量map,并在h2中再次借用。经典的解决方案是用Arc<Mutex<...>> Package map。但在上面的代码中,我们不需要锁定整个散列表。因为,尽管两个线程同时访问同一个散列表,但它们访问的是完全不同的区域。
所以我想通过线程共享map而不使用锁,但是我怎么才能获得它呢?我也开放使用不安全的 rust ...

shyt4zoc

shyt4zoc1#

在上面的代码中,我们不需要锁定整个散列表
事实上,我们有。
每次插入到HashMap中都可能触发它的重新分配,如果Map已经达到了它的容量。现在,想象一下下面的事件序列:

  • 第二个线程调用get并检索对该值的引用(在运行时它将只是一个地址)。
  • 第一个线程调用insert
  • Map被重新分配,旧的内存块现在无效。
  • 第二个线程取消引用先前检索到的引用-嘣,我们得到UB!

因此,如果您需要同时在Map中插入一些内容,您 * 必须 * 以某种方式进行同步。
对于标准的HashMap,唯一的方法是锁定整个Map,因为重新分配会使每个元素无效。如果使用类似DashMap的方法,它在内部同步访问,因此允许通过共享引用插入,这将不需要您进行锁定-但在API的其他部分中可能会比较麻烦(例如,您不能返回对map内部的值的引用-get方法返回RAII Package 器,用于同步),并且您可能会遇到意外的死锁。

相关问题