当前位置: 首页 > news >正文

rust学习(recursive mutex 实现)

问题:

编写如下代码的时候出现死锁:

pub fn test_double_lock() {let t = Arc::new(Mutex::new(1));let t1 = t.clone();let t2 = t.clone();let h = std::thread::spawn(move || {println!("hello trace1");let l1 = t1.lock().unwrap();println!("hello trace2");let l2 = t2.lock().unwrap();println!("hello trace3");});h.join().unwrap();
}

输出卡在了"hello trace2",这个原因主要是Rust的mutex是非recursive的 。所以同一个线程中如果出现2次获取锁,就会死锁掉。哈哈,网上查了一下,很多人都说recursive lock是垃圾代码,要修复。鉴于个人能力,很多这样的代码我都改不掉,所以我用Rust实现了一个recursive的锁。。。

主要数据结构

struct TarMutexRecord {m_count:u32, //1m_ownerid:Option<ThreadId> //2
}pub struct TarMutex {m_record:Mutex<TarMutexRecord>, //3m_cond:Condvar //4
}

1.获取锁计数,如果计数到0的话,唤醒其他等待线程去拿锁

2.锁的owner,每次拿到锁以后记录拿锁线程,防止其他线程调用unlock释放

3.#1,#2的数据记录

4.如果锁的owner不是当前线程,则调用这个m_cond等待。当锁释放的时候,如果计数为0,唤醒m_cond等待的线程。

主要接口

pub fn lock(&self) {let tid = std::thread::current().id();loop {let mut lock = self.m_record.lock().unwrap();if lock.m_count == 0 {//no ownerlock.m_count += 1; //1lock.m_ownerid = Some(tid); //2return;} else if let Some(ownerid) = lock.m_ownerid{if ownerid == tid {lock.m_count += 1;//3return;}}self.m_cond.wait(lock);//4}}pub fn unlock(&self) {let tid = std::thread::current().id();let mut lock = self.m_record.lock().unwrap();if let Some(ownerid) = lock.m_ownerid{if ownerid == tid {lock.m_count -= 1;//5if lock.m_count == 0 {lock.m_ownerid = None;self.m_cond.notify_all();//6}}}}

1.如果当前线程没有获取过锁,则只要计数+1

2.记录当前获取到锁线程id

3.如果当前线程已经获取过锁,则只要计数+1

4.如果当前有其他线程正在拿锁,则等待

5.锁释放时先计数-1

6.如果当前计数为0,表明锁都已经释放,直接唤醒所有等待锁的队列。

http://www.lryc.cn/news/335479.html

相关文章:

  • DasViewer可以添加照片到里面吗?点开就可以看照片?
  • python蓝桥杯选数
  • 联想电脑开启虚拟化失败,开启虚拟化却提示还没有开启虚拟化
  • 物联网农业四情在线监测系统
  • MySQL8.3.0 主从复制方案(master/slave)
  • 大数据相关组件安装及使用
  • 【攻防世界】web2(逆向解密)
  • Linux文件查找命令详解——以CentOS为例
  • 【JavaEE】浅谈线程(一)
  • 深度解析SPARK的基本概念
  • FreeGPT3.5 开源软件
  • AI绘本生成解决方案,快速生成高质量的AI绘本视频
  • RabbitMQ3.13.x之九_Docker中安装RabbitMQ
  • 【操作系统】STM32-操作系统——持续更新
  • Redux Toolkit+TypeScript最佳实践
  • 假期别闲着:REST API实战演练之创建Rest API
  • C++模仿qq界面
  • 3D模型在线轻量化工具
  • 去中心化社交媒体:分析 Facebook 在区块链平台上的角色
  • 实现多租户JAVA支付(微信拉起支付):一个简单而强大的解决方案
  • 万字长文:FineBI面试题及参考答案详解
  • Python爬虫:为什么你爬取不到网页数据
  • NLP在搜索召回领域中的应用场景
  • 2. Django配置信息
  • 【Web】纯萌新的BUUCTF刷题日记Day1
  • 【51单片机入门记录】RTC(实时时钟)-DS1302概述
  • Lua热更新(AssetBundle)
  • 互联网人才现状分析
  • 高级IO——多路转接
  • TypeScript常用知识点整理