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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM