首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >这些代码会使用Rust Dashmap产生死锁吗?

这些代码会使用Rust Dashmap产生死锁吗?
EN

Stack Overflow用户
提问于 2021-12-10 04:59:25
回答 1查看 693关注 0票数 2

这样的代码会不会在Rust中使用DashMap产生死锁?

代码语言:javascript
运行
复制
// snippet_1
let a = DashMap::new();
let b = DashMap::new();

// thread1
for v in a.iter(){
   xxx
}
for v in b.iter(){
   xxx
}

//thread2
for v in b.iter(){
   xxx
}
for v in a.iter(){
   xxx
}
代码语言:javascript
运行
复制
// snippet_2
let a = DashMap::new();
let b = DashMap::new();

// thread1
for v in a.iter(){
   xxx
}
for v in b.iter(){
   xxx
}

//thread2
for v in b.iter(){
   xxx
   for v in a.iter() {
      xxx
   }
   xxx
}
代码语言:javascript
运行
复制
// snippet_3
let a = DashMap::new();
let b = DashMap::new();

// thread1
for v in a.iter(){
   xxx
}
for v in b.iter(){
   xxx
}

//thread2
for v in b.iter(){
   xxx
   let Some(v) = a.get_mut(key){
      xxx
   }
   xxx
}

此外,在同一个线程中迭代时,插入到dashmap中将产生死锁。但是,从另一个线程插入到dashmap不会产生死锁。这是真的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-12-10 09:35:22

所有这些示例都不会产生死锁。

来自文档的

insert():在映射中插入一个键和一个值。返回与键关联的旧值(如果存在的话)。

锁定行为:如果将任何类型的引用保存到映射中时调用,则可能出现死锁。

iter():在生成不可变引用的DashMap上创建一个迭代器。

锁定行为:如果将可变引用保存到映射中时调用,则可能出现死锁。

get_mut():获取映射中一个条目的可变引用

锁定行为:如果将任何类型的引用保存到映射中时调用,则可能出现死锁。

Explanation:

在前两个示例中,只使用iter(),因此只要不使用将可变引用包含到映射中的其他操作,就不会出现死锁。

在您的第三个示例中,DashMap b只与iter()一起使用,因此没有死锁。对于DashMap a,有两个可能的执行流:

  1. 如果线程1首先到达a.iter(),那么线程2必须在a.get_mut(key)等待,但是一旦线程1完成了对a线程2的迭代,那么就不会出现死锁。如果线程2首先到达a.get_mut(key),那么线程1必须在a.iter()等待,但是一旦线程2完成,它将能够继续,并且不会出现死锁。H 226G 227

附加问题

在同一个线程中迭代DashMap时,插入到它中将产生死锁。

示例

代码语言:javascript
运行
复制
for v in a.iter() { // This takes a reference into `a`
    a.insert(...) // Will deadlock because you hold a reference into `a`
}

从一个线程插入到DashMap中,而在另一个线程中迭代它,不会产生死锁,其中一个只会等待另一个线程。

示例

代码语言:javascript
运行
复制
//thread1
for v in a.iter(){ //If thread2 reaches `insert()` first, this will wait until it has finished.
    xxx
}

//thread2
for i in 1..1000 {
    a.insert(i, i); // If thread1 reaches `iter()` first, this will wait until it has finished.
}

需要注意的是,在最后一个例子和问题的第三个例子中,insert()和iter()可能不会等待整个循环在开始之前完成,相反,两个循环的执行将被交错,但它们永远不会在完全同时执行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70299926

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档