当前位置:   article > 正文

rust学习(recursive mutex 实现)

rust学习(recursive mutex 实现)

问题:

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

  1. pub fn test_double_lock() {
  2. let t = Arc::new(Mutex::new(1));
  3. let t1 = t.clone();
  4. let t2 = t.clone();
  5. let h = std::thread::spawn(move || {
  6. println!("hello trace1");
  7. let l1 = t1.lock().unwrap();
  8. println!("hello trace2");
  9. let l2 = t2.lock().unwrap();
  10. println!("hello trace3");
  11. });
  12. h.join().unwrap();
  13. }

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

主要数据结构

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

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

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

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

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

主要接口

  1. pub fn lock(&self) {
  2. let tid = std::thread::current().id();
  3. loop {
  4. let mut lock = self.m_record.lock().unwrap();
  5. if lock.m_count == 0 {
  6. //no owner
  7. lock.m_count += 1; //1
  8. lock.m_ownerid = Some(tid); //2
  9. return;
  10. } else if let Some(ownerid) = lock.m_ownerid{
  11. if ownerid == tid {
  12. lock.m_count += 1;//3
  13. return;
  14. }
  15. }
  16. self.m_cond.wait(lock);//4
  17. }
  18. }
  19. pub fn unlock(&self) {
  20. let tid = std::thread::current().id();
  21. let mut lock = self.m_record.lock().unwrap();
  22. if let Some(ownerid) = lock.m_ownerid{
  23. if ownerid == tid {
  24. lock.m_count -= 1;//5
  25. if lock.m_count == 0 {
  26. lock.m_ownerid = None;
  27. self.m_cond.notify_all();//6
  28. }
  29. }
  30. }
  31. }

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

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

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

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

5.锁释放时先计数-1

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/427601
推荐阅读
相关标签
  

闽ICP备14008679号