线程安全之死锁

目录

一、概念

二、例子

三、死锁相关面试题目


一、概念

死锁主要发生在有多个依赖锁存在时,会在一个线程试图以另一个线程相反顺序锁住互斥量时发生

死锁使得一个或多个线程被挂起而无法继续执行,最糟糕的是,这种情况还不容易被发现。

在一个线程中对一个已经加锁的普通锁再次加锁,将导致死锁

这种情况可能出现在设计得不够仔细地递归函数中。

另外,如果两个线程按照不同的顺序来申请两个互斥锁,也容易发生死锁

二、例子

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <unistd.h>
#include <pthread.h>int a=0;
int b=0;
pthread_mutex_t mutex_a;
pthread_mutex_t mutex_b;
void *another(void *arg)
{pthread_mutex_lock(&mutex_b);printf("in child thread,got mutex b,waiting for mutex a\n");sleep(5);++b;pthread_mutex_lock(&mutex_a);b+=a++;pthread_mutex_unlock(&mutex_a);pthread_mutex_unlock(&mutex_b);pthread_exit(NULL);
}int main()
{pthread_t id;pthread_mutex_init(&mutex_a,NULL);pthread_mutex_init(&mutex_b,NULL);pthread_create(&id,NULL,another,NULL);pthread_mutex_lock(&mutex_a);printf("in parent thread,got mutex a,waiting for mutex b\n");sleep(5);++a;pthread_mutex_lock(&mutex_b);a+=b++;pthread_mutex_unlock(&mutex_b);pthread_mutex_unlock(&mutex_a);pthread_join(id,NULL);pthread_mutex_destroy(&mutex_a);pthread_mutex_destroy(&mutex_b);exit(0);
}

主线程试图先占有互斥锁mutex_a,然后操作被该锁保护的变量a,但操作完毕之后,主线程并没有立即释放互斥锁mutex_a,而是又申请互斥锁mutex b,并在两个互斥锁的保护下,操作变量a和b,最后才一起释放这两个互斥锁;

于此同时,子线程则按照相反的顺序来申请互斥锁mutex_a和mutex_b,并在两个锁的保护下操作变量a和b;

我们用sleep函数来模拟连续两次调用pthread_mutex_lock之间的时间差,以确保代码中的两个线程各自先占用一个互斥锁(主线程占有mutex_a,子线程占有mutex_b),然后等待另外一个互斥锁(主线程等待mutex_b,子线程等待mutex_a).这样,两个线程就僵持住了,谁也不能继续往下执行,从而形成死锁.

如果代码中不加入sleep函数,则这段代码或许总能成功地运行,从而为程序留下了一个潜在地bug.

如何避免死锁是使用互斥量应该格外注意的东西

  • 总体来讲,有几个不成文的基本规则:
  • 对共享资源操作前一定要获得锁;
  • 完成操作以后一定要释放锁;
  • 尽量短时间地占用锁;
  • 如果有多个锁,如获得顺序是ABC连环扣.释放顺序也应该是ABC;
  • 线程错误返回时应该释放它所获得的锁;

三、死锁相关面试题目

问题:如何避免死锁?
解答:
死锁的概念:多个进程或线程访问一组竟态资源的时候,出现的永久阻塞的问题。也可以这么说:指两个或两个以上的线程或进程在执行程序的过程中,因争夺资源或者程序推进顺序不当而相互等待的一个现象。
产生的原因主要有三个:系统资源不足,程序运行推进的顺序不当,资源分配不当。

或者说:死锁产生的必要条件是:

  • 互斥条件
  • 请求和保持条件
  • 不剥夺条件
  • 环路等待条件

避免死锁就是打破这四个条件中的某一个即可。如某个进程申请多个资源,只要有一个资源不满足暂时就不要分配任何资源。等所有资源能满足时一起分配。
处理死锁的基本方法?

  • 预防死锁
  • 避免死锁(银行家算法)
  • 检测死锁(资源分配)
  • 解除死锁:剥夺资源、撤销进程

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/518838.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot-整合mybatis

1.导入依赖 <!--整合mybatis--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><!--mysql--><dependen…

为什么不从独立服务器中转向云或其他方案呢?

传统的专用服务器&#xff0c;如香港服务器租赁、重庆服务器租赁等&#xff0c;是最强大、最稳定的业务托管类型之一。您将获得比任何其他托管计划更多的管理权限和卓越的性能&#xff0c;并且您可以控制整个服务器上的几乎所有内容。 当然&#xff0c;专用服务器也是在线业务…

多线程:线程池

线程池 认识线程池 什么是线程池 线程池就是一个可以复用线程的技术。 不使用线程池的问题 用户每发起一个请求&#xff0c;后台就需要创建一个新线程来处理&#xff0c;下次新任务来了肯定又要创建新线程处理的&#xff0c;而创建新线程的开销是很大的&#xff0c;并且请…

蜻蜓FM语音下载(mediadown)

一、介绍 蜻蜓FM语音下载&#xff08;mediadown&#xff09;&#xff0c;能够帮助你下载蜻蜓FM音频节目。如果你是蜻蜓FM会员&#xff0c;它还能帮你下载会员节目。 二、下载地址 本站下载&#xff1a;蜻蜓FM语音下载&#xff08;mediadown&#xff09; 百度网盘下载&#…

爬虫入门到精通_框架篇15(Scrapy框架安装)

1 Scrapy安装 Scrapy的安装有多种方式&#xff0c;它支持Python2.7版本及以上或Python3.3版本及以上。下面说明Python3环境下的安装。 Scrapy依赖的库比较多&#xff0c;至少需要依赖库有Twisted14.0,lxml 3.4,pyOpenSSL 0.14。而在不同平台环境又各不相同&#xff0c;所以在安…

【Flutter 面试题】dart是值传递还是引用传递?

【Flutter 面试题】dart是值传递还是引用传递&#xff1f; 文章目录 写在前面解答补充说明值传递示例引用传递示例总结 写在前面 关于我 &#xff0c;小雨青年 &#x1f449; CSDN博客专家&#xff0c;GitChat专栏作者&#xff0c;阿里云社区专家博主&#xff0c;51CTO专家博主…

视频编码中常用的测试YUV系列及说明

vcc最新规定的测试序列如下所示&#xff0c;对于RA和LD配置&#xff0c;所有序列的所有帧都需要测试&#xff0c;对于intra配置仅需测试前8帧。 每列含义如下&#xff1a; A1、A2测试序列在LD配置下编码时应编码帧数为帧率的三倍。 “M”表示在该配置下必须测试这条序列。 …

算法沉淀——动态规划之其它背包问题与卡特兰数(leetcode真题剖析)

算法沉淀——动态规划之其它背包问题与卡特兰数 二维费用的背包问题01.一和零02.盈利计划 似包非包组合总和 Ⅳ 卡特兰数不同的二叉搜索树 二维费用的背包问题 01.一和零 题目链接&#xff1a;https://leetcode.cn/problems/ones-and-zeroes/ 给你一个二进制字符串数组 strs…

登录校验-过滤器-拦截器

会话技术 会话&#xff1a;用户打开浏览器&#xff0c;访问Wb服务器的资源&#xff0c;会话建立&#xff0c;直到有一方断开连接&#xff0c;会话结束。在一次会话中可以包含多次请求和响应。 会话跟踪&#xff1a;一种维护浏览器状态的方法&#xff0c;服务器需要识别多次请求…

【MySQL知识体系】第2章 数据库与表的创建(一)

第2章 数据库与表的创建 2.1 数据库操作 2.2 表操作 文章目录 第2章 数据库与表的创建2.1 数据库操作2.1.1 创建第一个数据库2.1.2 更新数据库名称&#xff08;数据库创建后无法修改名称&#xff09;2.1.3 删除数据库2.1.4 取个合适的数据库名称 第2章 数据库与表的创建 2.1 数…

抖音商家短视频直播流量变现运营SOP地图

【干货资料持续更新&#xff0c;以防走丢】 抖音商家短视频直播流量变现运营SOP地图 部分资料预览 资料部分是网络整理&#xff0c;仅供学习参考。 抖音运营资料合集&#xff08;完整资料包含以下内容&#xff09; 目录 【提升短视频运营效率的专业指南】 高效运营&#xf…

浅谈Linux进程隐藏

浅谈Linux进程隐藏 文章目录 浅谈Linux进程隐藏前言环境变量的绕过常用的命令在哪里环境变量的调用前置知识的了解Netstat伪装怎么去甄别 LD_PRELOAD简单实例check.c重载函数设置LD_PERLOAD删除环境变量LD_PERLOAD PS的隐藏readdir函数如何HOOK编译并验证 LD_PRELOAD的其他利用…