简单示例

举个例子,桌上有一支笔和一张纸,小A和小B都要拿到纸笔写字

小A拿了笔,小B拿了纸,这时就形成了死锁(两人都不愿意让出纸笔)。

其实只要稍加控制就可以避免这种情况:规定必须先拿到纸再能去尝试拿笔;

......

上面这个例子里相当于存在两个mutex,一个对纸进行“访问控制”(记作mutex1),一个对笔进行“访问控制”(记作mutex2);

小A的加锁顺序是mutex2, mutex1;

小B是mutex1, mutex2

很多情况都是不同线程对多个mutex加锁顺序不一致导致死锁发生

std::lock(...)

最简单的就是保证每个线程加锁的顺序都是一致的,

c++提供了一个方法std::lock,可以传入任意数量的lockable对象,然后c++使用某种死锁避免算法保证死锁不会发生

std::lock(mutex1, mutex2);
std::lock_guard<std::mutex> lock1(mutex1, std::adopt_lock);
std::lock_guard<std::mutex> lock2(mutex2, std::adopt_lock);
...

上面的lock_guard传入了std::adopt_lock参数,意在告诉lock对象mutex已经加锁了,lock_guard需要做的只是在离开作用域时调用unlock

小结

  • 如果能用单个mutex,就不要使用多个mutex
  • 尽量不要在mutex的lock-unlock块里调用其它自定义函数,防止自定义函数里有不安全的处理,如给同一个mutex加了锁、抛出异常等等
  • 当使用了多个mutex时,使用std::lock函数;如果情况特殊,使用std::lock不方便,也要保证每个线程加锁的顺序一致

c++11多线程记录4:死锁的更多相关文章

  1. c++11多线程记录0

    两种并发编程模型 多进程 进程间通信常用的几种方式: 文件 管道 消息队列 多线程 一个进程中存在的多个线程,通常通过共享内存来通信,(说的非常非常粗俗,就是通过类似"全局变量"的 ...

  2. c++11多线程记录6:条件变量(condition variables)

    https://www.youtube.com/watch?v=13dFggo4t_I视频地址 实例1 考虑这样一个场景:存在一个全局队列deque,线程A向deque中推入数据(写),线程B从deq ...

  3. c++11多线程记录5: Unique Lock和延时初始化

    https://www.youtube.com/user/BoQianTheProgrammer 视频网址 Unique Lock unique_lock和lock_guard类似,都是mutex的w ...

  4. c++11多线程记录3: 数据争用和Mutex的使用

    https://www.youtube.com/watch?v=3ZxZPeXPaM4 学习视频 数据争用 简单来说就是存在多个线程同时对某个共同的对象进行读写(至少有一个线程在做写操作),造成读取这 ...

  5. c++11多线程记录2:线程管理

    线程没有调用join和detach thread对象必须调用join或者detach,否则程序会终止 例如: void func() { std::cout << "hello, ...

  6. c++11多线程记录1 -- std::thread

    启动一个线程 话不多说,直接上代码 void func(); int main() { std::thread t(func); //这里就开始启动线程了 t.join(); // 必须调用join或 ...

  7. 《C#多线程编程实战》1.11 Monitor.TryEnter()避免死锁

    这章的内容是真的有意思 特别是代码. 先贴上代码: class Program { static void Main(string[] args) { object lock1 = new objec ...

  8. c++11 多线程 -- 基本使用

    c++11 多线程 – 基本使用 前言:这篇文章仅针对没有使用过c++11线程库的童鞋来高速入门,也是自己的一个简单记录,内容比較基础. 1.线程的基本使用 2.相互排斥量 3.条件变量 4.原子变量 ...

  9. java 多线程争抢资源死锁

    多线程争抢资源死锁的原理就是,A线程正在持有锁1却想获取锁2,B线程正在持有锁2却要获取锁1 代码如下: public class Main { static ReentrantLock lock1 ...

随机推荐

  1. netflix flamescope 方便的不同时间范围的火焰图查看工具

    flamescope 是netflix 开源的方便的火焰图查看工具,我们可以选择不同时间范围的数据,方便分析调用链 环境准备 使用docker-compose运行,基于官方的dockerfile 创建 ...

  2. 发现Xilinx Virtex 5 FPGA中单个DSP乘法器只支持17位无符号乘法

    发现Xilinx Virtex 5 FPGA中,单个DSP乘法器只支持17位无符号乘法.如果令18位乘数相乘,结果会与正确的乘积不同.

  3. create-react-app不支持less的解决方式

    进入node_modules\react-scripts\config目录 修改webpack.config.dev.js跟webpack.config.prod.js中关于loader的配置即可,注 ...

  4. shell脚本获取传入参数的个数

    ts.sh #!/bin/bash echo $# 输出 [root@redhat6 ~]# ./ts.sh para1 [root@redhat6 ~]# ./ts.sh para1 para2 [ ...

  5. [Gamma]Scrum Meeting#3

    github 本次会议项目由PM召开,时间为5月28日晚上10点30分 时长10分钟 任务表格 人员 昨日工作 下一步工作 木鬼 撰写博客,组织例会 撰写博客,组织例会 swoip 前端显示屏幕,翻译 ...

  6. Java事务以及嵌套事务

    知识点:java事务属性 Propagation取值: REQUIRED(默认值):在有transaction状态下执行:如当前没有transaction,则创建新的transaction: SUPP ...

  7. gradle/gradle plugin/Android studio关系

    gradle - 构建工具,存储于Users/stono/.gradle/wrapper/dists Adroid Studio- IDE Gradle plugin - 在AS中使用Gradle的插 ...

  8. linux下使用clamav排查病毒

    clamav wget http://www.clamav.net/downloads/production/clamav-0.102.0.tar.gz ### Installyum -y insta ...

  9. 源码编译Redis Desktop Manager ---(转载)

    精美文章转载: 版权声明:本文作者为「Kany.Wang」,本博客所有文章除特别声明外,均采用 CC BY-NC-SA 3.0 许可协议.转载请注明出处!原文链接:https://kany.me/20 ...

  10. 【转载】 GPU状态监测 nvidia-smi 命令详解

    原文地址: https://blog.csdn.net/huangfei711/article/details/79230446 ----------------------------------- ...