设为首页 加入收藏

TOP

c/c++ 多线程 层级锁
2018-11-05 22:08:28 】 浏览:23
Tags:c/c 线程 层级

多线程 层级锁

当要同时操作2个对象时,就需要同时锁定这2个对象,而不是先锁定一个,然后再锁定另一个。同时锁定多个对象的方法:std::lock(对象1.锁,对象2.锁...)

但是,有的时候,并不能同时得到所有要锁定的锁,必须是先锁定某个后,再锁定其他的,这种情况就不能使用std::lock函数了,怎么办呢,使用有顺序的锁。

额外说明:lock_guard<模板类> ,中模板类的实现。这个模板类只要实现mutex所需要的三个成员函数即可:lock(), unlock(), try_lock()。

例子:lock_guard的模板类hierarchical_mutex

class hierarchical_mutex{
  std::mutex mtx;
  unsigned long const hcl_val;
  unsigned long pre_hcl_val;

  static thread_local unsigned long this_hcl_val;

  void check_for_hcl_violaction(){
    if(this_hcl_val <= hcl_val){
      throw std::logic_error("mutex hierarchy violated");
    }
  }
  void update_hierarchy_value(){
    pre_hcl_val = this_hcl_val;
    this_hcl_val = hcl_val;
  }

public:
  explicit hierarchical_mutex(unsigned long val):
    hcl_val(val), pre_hcl_val(0){}

  void lock(){
    check_for_hcl_violaction();
    mtx.lock();
    update_hierarchy_value();
  }

  void unlock(){
    this_hcl_val = pre_hcl_val;
    mtx.unlock();
  }

  bool try_lock(){
    check_for_hcl_violaction();
    if(!mtx.try_lock())
      return false;
    update_hierarchy_value();
    return true;
  }
};

顺序锁的应用例子:当要锁定时某个锁时,要先检查已经上锁的锁的序号,如果序号低于现在要锁的锁的序号的话就可以锁定,否则,抛出异常。

我也没理解锁的序号的真正含义,只是做个记录,抄一个例子。。。

#include <mutex>
#include <climits>//ULONG_MAX
#include <thread>

class hierarchical_mutex{
  std::mutex mtx;
  unsigned long const hcl_val;
  unsigned long pre_hcl_val;

  static thread_local unsigned long this_hcl_val;

  void check_for_hcl_violaction(){
    if(this_hcl_val <= hcl_val){
      throw std::logic_error("mutex hierarchy violated");
    }
  }
  void update_hierarchy_value(){
    pre_hcl_val = this_hcl_val;
    this_hcl_val = hcl_val;
  }

public:
  explicit hierarchical_mutex(unsigned long val):
    hcl_val(val), pre_hcl_val(0){}

  void lock(){
    check_for_hcl_violaction();
    mtx.lock();
    update_hierarchy_value();
  }

  void unlock(){
    this_hcl_val = pre_hcl_val;
    mtx.unlock();
  }

  bool try_lock(){
    check_for_hcl_violaction();
    if(!mtx.try_lock())
      return false;
    update_hierarchy_value();
    return true;
  }
};

thread_local unsigned long
hierarchical_mutex::this_hcl_val(ULONG_MAX);

hierarchical_mutex high_level_mutex(10000);
hierarchical_mutex low_level_mutex(5000);

int do_low_level_stuff(){
  return 1;
}
int low_level_func(){
  std::lock_guard<hierarchical_mutex> lk(low_level_mutex);
  return do_low_level_stuff();
}

void high_level_stuff(int param){
  
}
void high_level_func(){
  std::lock_guard<hierarchical_mutex> lk(high_level_mutex);
  high_level_stuff(low_level_func());
}

void thread_a(){
  high_level_func();
}

hierarchical_mutex other_mutex(100);
void do_other_stuff(){
  
}

void other_stuff(){
  high_level_func();
  do_other_stuff();
}

void thread_b(){
  std::lock_guard<hierarchical_mutex> lk(other_mutex);
  other_stuff();
}

int main(){
  //锁定顺序合法(因为先锁的大的,后锁的小的)
  std::thread a(thread_a);
  //锁定顺序非法(因为先锁的小的,后锁的大的)
  std::thread b(thread_b);
  a.join();
  b.join();
}

github源代码

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854


编程开发网
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇解析·NOIP·冷门 CLZ最小环 下一篇SPOJTLE - Time Limit Exceeded(..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

array(4) { ["type"]=> int(8) ["message"]=> string(24) "Undefined variable: jobs" ["file"]=> string(32) "/mnt/wp/cppentry/do/bencandy.php" ["line"]=> int(214) }