多线程 层级锁

当要同时操作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

c/c++ 多线程 层级锁的更多相关文章

  1. 在SQL Serve里停用行和页层级锁

    今天我想谈下SQL Server里另一个非常有趣的话题:在SQL Server里停用行和页层级锁.在SQL Server里,每次你重建一个索引,你可以使用ALLOW_ROW_LOCKS 和ALLOW_ ...

  2. SDL 开发实战(七): SDL 多线程与锁机制

    为什么要用多线程?在音视频领域主要是实现音视频同步.实现了音视频同步,我们的播放器就基本上合格了. 这里我们将讲解一下SDL的多线程与锁机制. 多线程的好处主要是能使程序更加充分利用硬件(主要是CPU ...

  3. C 语言多线程与锁机制

    C 语言多线程与锁机制 多线程 #include <pthread.h> void *TrainModelThread(void *id) { ... pthread_exit(NULL) ...

  4. Android并发编程 多线程与锁

    该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,如果能给各位看官带来一丝启发或者帮助,那真是极好的. 前言 前一篇Android并发编程开篇呢,主要是简单介绍一下线程以及 ...

  5. 多线程-synchronized锁

    package 多线程.synchronized锁; /*. * * * * */ public class Sale implements Runnable { ; @Override public ...

  6. 多线程-lock锁

    package 多线程.lock锁; import java.util.concurrent.locks.ReentrantLock; /*. * * //同步代码块 * * */ public cl ...

  7. 第十五章、Python多线程同步锁,死锁和递归锁

    目录 第十五章.Python多线程同步锁,死锁和递归锁 1. 引子: 2.同步锁 3.死锁 引子: 4.递归锁RLock 原理: 不多说,放代码 总结: 5. 大总结 第十五章.Python多线程同步 ...

  8. Java多线程--公平锁与非公平锁

    上一篇文章介绍了AQS的基本原理,它其实就是一个并发包的基础组件,用来实现各种锁,各种同步组件的.它包含了state变量.加锁线程.等待队列等并发中的核心组件,现在我们来看一下多线程获取锁的顺序问题. ...

  9. JAVA多线程与锁机制

    JAVA多线程与锁机制 1 关于Synchronized和lock synchronized是Java的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码 ...

随机推荐

  1. 巡风源码阅读与分析---nascan.py

    Nascan是巡风主要是做目标的资产识别(信息收集). nascan.py 文件位于 nascan/nascan.py # coding:utf-8 # author:wolf@YSRC import ...

  2. 北上广等一线城市IT岗位已接近饱和?

    IT行业的技术者,时常被我们戏称为「IT民工」,虽然行业内巨大的人才需求和相对容易得到的高薪在源源不断的吸引各路人马加入,但它依旧在全球最缺人的十大行业中位居榜首. 我身边的朋友大都问过我这样一个疑问 ...

  3. IntelliJ IDEA 自定义方法注解模板

    最近没啥事开始正式用Eclipse 转入 idea工具阵营,毕竟有70%的开发者在使用idea开发,所以它的魅力可想而知.刚上手大概有一天,就知道它为啥取名为 intelli(智能化)了,确实很智能, ...

  4. BBS论坛(二)

    2.1.cms后台登录界面完成 (1)templates/cms/cms_login.html <!DOCTYPE html> <html lang="zh-CN" ...

  5. GitHub 1W star 成就达成!

    起因 感谢各位大佬的支持收获了人生第一个(很有可能也是唯一一个)1W star 项目. 从今年一月份创建项目至今 8 个月时间. 一共关闭了 27 个 issue,47 个 RP,总共有 11 位小伙 ...

  6. Guava 源码分析(Cache 原理)

    前言 Google 出的 Guava 是 Java 核心增强的库,应用非常广泛. 我平时用的也挺频繁,这次就借助日常使用的 Cache 组件来看看 Google 大牛们是如何设计的. 缓存 本次主要讨 ...

  7. java代码之美(4)---guava之Immutable(不可变)集合

    Immutable(不可变)集合 一.概述 guava是google的一个库,弥补了java语言的很多方面的不足,很多在java8中已有实现,暂时不展开.Collections是jdk提供的一个工具类 ...

  8. ES 04 - 安装Kibana插件(6.6.0版本)

    目录 1 Kibana是什么 2 安装并启动Kibana 2.1 准备安装包 2.2 修改配置文件 2.3 启动Kibana并验证 2.4 关闭Kibana服务 3 Kibana功能测试 3.1 关于 ...

  9. 带着萌新看springboot源码04

    继续开头说些废话,我也不知道什么鬼,每次写着写着经常会写到其他地方去了,太容易分神了. 这次说一下springboot对于springmvc的大概整个流程,以请求动态网页为例 . 1.梳理一下spri ...

  10. 在Flutter中嵌入Native组件的正确姿势是...

    引言 在漫长的从Native向Flutter过渡的混合工程时期,要想平滑地过渡,在Flutter中使用Native中较为完善的控件会是一个很好的选择.本文希望向大家介绍AndroidView的使用方式 ...