08-死锁

2020/07/03 cpp_concurrency 共 1165 字,约 4 分钟

造成死锁的原因很多,总的一句话就是资源不可用。在多线程中,造成死锁的原因无外乎多个线程相互之间等待自己没有的资源。避免死锁的建议:

  • 避免嵌套锁:也就是一个线程只拥有一个锁
  • 避免在持有锁时调用用户提供的代码:用户的代码是不可信的,你不知道它在里面干啥,是造飞机还是打游戏
  • 使用固定顺序获取锁:保证加锁和解锁的顺序固定。但是这个方法并不可靠,因为代码可能比较复杂~
  • 使用层次锁:一个线程在加锁前先去判断是否已经拥有了锁,如果以前加锁的层次大于当前层次则不允许加锁。并且如果要获取多个锁,那么应该一次获取完毕!

上面前面的3个建议都比较好理解,第四个在CCIA中有一个层次锁的实现类,如下:

class hierarchical_mutex
{
  std::mutex internal_mutex;

  unsigned long const hierarchy_value;
  unsigned long previous_hierarchy_value;

  static thread_local unsigned long this_thread_hierarchy_value;  // 1

  void check_for_hierarchy_violation()
  {
    if(this_thread_hierarchy_value <= hierarchy_value)  // 2
    {
      throw std::logic_error(mutex hierarchy violated);
    }
  }

  void update_hierarchy_value()
  {
    previous_hierarchy_value=this_thread_hierarchy_value;  // 3
    this_thread_hierarchy_value=hierarchy_value;
  }

public:
  explicit hierarchical_mutex(unsigned long value):
      hierarchy_value(value),
      previous_hierarchy_value(0)
  {}

  void lock()
  {
    check_for_hierarchy_violation();
    internal_mutex.lock();  // 4
    update_hierarchy_value();  // 5
  }

  void unlock()
  {
    this_thread_hierarchy_value=previous_hierarchy_value;  // 6
    internal_mutex.unlock();
  }

  bool try_lock()
  {
    check_for_hierarchy_violation();
    if(!internal_mutex.try_lock())  // 7
      return false;
    update_hierarchy_value();
    return true;
  }
};

文档信息

Search

    Table of Contents