简单示例

举个例子,桌上有一支笔和一张纸,小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. (尚028)Vue_案例_交互删除

    删除一条;1.鼠标移入移除这一条时颜色有变化 2.删除当前的todo ================================================================= ...

  2. 第04组alpha冲刺(2/4)

    队名:斗地组 组长博客:地址 作业博客:Alpha冲刺(2/4) 各组员情况 林涛(组长) 过去两天完成了哪些任务: 1.收集各个组员的进度 2.写博客 展示GitHub当日代码/文档签入记录: 接下 ...

  3. 灰度图像--图像分割 Prewitt算子

    学习DIP第45天 转载请标明本文出处:http://blog.csdn.net/tonyshengtan,欢迎大家转载,发现博客被某些论坛转载后,图像无法正常显示,无法正常表达本人观点,对此表示很不 ...

  4. SpringCloud基本模块分配搭建以及负载均衡

    springcloud是基于springboot的一套微服务的解决方案,springboot可以快速构建单个应用服务,而springcloud没有重复造轮子而是将现有的技术(服务发现,负载均衡等)整合 ...

  5. Xilinx ISE中使用Synplify综合报错的原因之二

    今天发现,不同的器件型号下由IP core生成的模块有时不通用,在实现(implementation)时会出现translate错误.

  6. nginx 访问控制之 request_uri

    $request_uri比$docuemnt_uri多了请求的参数. 主要用来针对请求的uri中的参数进行控制. 示例: if ($request_uri ~ "gid=\d{9,12}&q ...

  7. js读取sqlserver数据库,输出至html

    代码: <!DOCTYPE html> <html> <head>   <meta charset="utf-8">   <m ...

  8. Appium入门脚本

    没有用框架的代码实现登录功能: import time from selenium import webdriver # 创建字典 desired_caps = {} desired_caps['pl ...

  9. <每日 1 OJ> -Table

    上图是一个Mysql查询结果图,我们看到这个表格非常漂亮,只需要使用”+”和”-”两个符号就可以打印,现在你的任务是打印一个n×m的表格我们定义单位长度(水平方向有三个”-”,竖直方向有一个”| ”, ...

  10. OO助教的退休感想

    深夜失眠+刚赶完火车的胡言乱语,切莫当真,择日修改 一年前,我在学姐的怂恿鼓励下,加上了吴老师的微信,表达了想担任下学期的OO助教的想法.三天后,我到新主楼参加OO助教的面试,其实还是蛮紧张的,毕竟自 ...