Linux学习之系统编程篇:死锁的情形及其解决
(1)自己锁自己(自己重复加同一个锁)
解决:上锁,自己操作完成后,一定要解锁 lock 和 unlock 成对出现
举例:
for(int i = 0; i < MAX; i++)
{// 加锁pthread_mutex_lock(&mutex); // 第一次循环,没解锁,第二次循环,执行至此,由于发现有锁,因此阻塞代码……// 没有解锁
}
对于此处内核设计的思考:
锁的类型 pthread_mutex_t 本质上是一个结构体。这个结构体中会有一个成员属性(假设是flag),用于判断是否上锁,int型,其值是0或者1,1代表有一把锁可用,意味着没锁,而0代表有锁,当某线程执行到pthread_mutex_lock,内核会通过 flag 判断是否上锁,只要是上锁状态,所有线程都会被组设,因为在设计时候就决定了,它只关心是否上锁,而不会关心是谁上的锁,因此会出现自己锁住自己的现象。
试想:在设计的时候,在结构体中,增加一个属性,用于判断是哪个线程上的锁,执行到pthread_mutex_lock,先判断是否上锁,如果上锁,再判断是否是我上的锁,这样就将“普通锁”变为“指纹锁”,就可以避免自己锁住自己的情况了。
(2)多个共享数据,多个锁,某些情况下,可能会造成死锁。
如上图所示,就会造成“线程 1 阻塞在 B 锁”和“线程 2 阻塞在 A 锁”的现象。
解决:
方式 1:造成这总的死锁的原因是线程访问顺序不一样:
线程 1 :A->B ;
线程 2 :B->A
因此:让线程按照一定的顺序去访问共享资源。
方式 2:在访问其他锁的时候,需要先将自己的锁解开。
方式 3:使用 trylock。
Linux学习之系统编程篇:死锁的情形及其解决相关推荐
- Linux学习之系统编程篇:ps 和 kill 命令以及父子进程间数据共享模式
一.ps 和 kill 命令 1.ps 命令 常用方式: ps aux :查看正在运行进程信息(主要查 pid). ps ajx :更加详细(PID. PPID:父进程 id. PGID:进程组 id ...
- Linux学习之系统编程篇:对线程的基本认识
(1)fork()后创建的子进程是父进程的拷贝,那么pthread_create,创建线程,创建的线程跟原进程有什么关系呢? fork 会通过拷贝产生新的虚拟地址空间(PCB 会变化),而 pthre ...
- Linux学习之系统编程篇:编写一个守护进程
需求:写一个守护进程,每隔 2s 获取一次系统时间,将这个时间写入到磁盘文件 #include <stdio.h> #include <stdlib.h> #include & ...
- Linux学习之系统编程篇:守护进程(精灵进程、后台进程)
一.背景 一般情况下,启动终端(shell),系统会创建一个会话(shell 进程是会长),经过后续各种操作,该会话中会存在多个进程组,每个进程组中也会有多个进程(父进程是组长),若此时关闭 shel ...
- Linux学习之系统编程篇:shm 共享内存及其操作函数
一.shm 和 mmap 的区别 (1)mmap 是在磁盘上建立一个文件,每个进程地址空间中开辟出一块空间进行映射.shm 每个进程最终会映射到同一块物理内存.shm 保存在物理内存,这样读写的速度最 ...
- Linux学习之系统编程篇:IPC 和管道的基本概念及管道的创建
一.IPC 概念 IPC: 进程间通信. 进程间通信的常见的 4 中方式: (1)管道 pipe fifo :最简单(但只能在有血缘关系下进行). (2)信号 signal : 属于系统的,所以系统开 ...
- Linux学习之系统编程篇:exec 函数族
函数能力:"换核不换壳"(能够替换进程虚拟地址空间中.text 代码段). 作用:让父子进程执行不相干的操作. 效果:有一个运行的程序 A,在 A 中调用另一个程序 B,程序有父子 ...
- Linux学习之系统编程篇:MMU(Memory Manager Unit 内存管理单元)
一.虚拟内存地址 对应于上图的两端,其中 0 - 3G 是用户区 ,3 - 4G 是内核区.编码的内存地址都是虚拟地址. 在3G到4G之间是PCB 进程控制块.从3G到0依次为: (1)命令行参数 和 ...
- Linux学习之系统编程篇:使用信号量实现“生产者和消费者模型”
模型中,最为关键的步骤是,在生产者回调函数中,未生产之前,消费者回调函数是阻塞的,阻塞方式是条件变量. 那么不使用条件变量,如何使用"信号量"实现阻塞呢? 答案是因为调用 sem_ ...
最新文章
- python入门代码示例-总算知道python入门代码示例
- docker学习笔记(一)docker入门
- windows下,linux下c++生成文件夹
- 电视看板实现原理_电脑显示器如何改装成电视机?详细改装方法,修电脑师傅告诉你...
- Linux无法连接远程仓库,ssh无法连接到远端Ubuntu的解决方法
- 单细胞转录组基本概念(一)
- python的前端开发_Python开发【前端】:html
- Android apk系列1-------APK签名
- 【Java程序设计】JDBC与数据库访问
- android圆饼图占比
- Automator——为mac创建自定义mac右键菜单
- 写在今年(2022)清明节前
- android代码 发警报音,Android 8中的警报重复
- 2010年北京大学软件与微电子学院毕业生就业去向(官方不完全统计)
- do while 循环 语法结构
- mysql远程连接报错2058
- 镜像 网站 linux 程序,腾讯开源镜像网站(腾讯云软件源)地址,附使用说明
- 手动挡停车技巧;换挡注意
- 快牛策略——嵌入式计算机
- 他们用折纸解决了两个数学难题,还折出了天文望远镜!!
热门文章
- 入门必备!生物医学命名实体识别(BioNER)最全论文清单,附SOTA结果汇总
- PaperWeekly 第52期 | 更别致的词向量模型:Simpler GloVe - Part 1
- 【Java】基于注解开发初探
- POJ1185 炮兵阵地 状压DP
- python中关键字参数的特点_Python中的*可变参数与**关键字参数
- FastDFS 学习笔记
- php redis 主从配置,Redis主从及其PHP扩展安装配置
- kettle从入门到精通_数据分析师的全景职业规划,入门、转行都先看这篇
- 网站如何接入微信支付功能?微信支付详细教程它来了(建议收藏)
- linux的基本命令--常用