39 死锁

目录

1.死锁
2.线程同步
3.条件变量
4.案例

死锁

概念

死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所占用不会释放的资源而处于的一种永久等待状态

四个必要条件

互斥条件:一个资源每次只能被一个执行流使用
请求与保持:一个执行流因请求资源而阻塞时,对已获得资源保持不放
不剥夺条件:一个执行流已获得的资源,在未使用完之前,不能强行剥夺
循环等待条件:若干执行流之间形成一种头尾相接的循环等待资源的关系,a的执行需要申请b的不释放资源,b的执行需要a的不释放资源

避免死锁

破坏死锁的四个必要条件。第一个互斥条件需要重写逻辑结构,比较困难。二和三都有对应的函数,请求与保持在加锁的时候是阻塞等待,有一个函数加锁是非阻塞等待的
加锁顺序一致
避免锁未释放的场景
资源一次性分配。资源不要分好几次给,一次性给完。就等减少死锁的可能

算法

避免死锁算法
银行家算法

线程同步

概念

上一节的买票程序,会出现只有一个线程经常抢到票。根本原因是线程对锁的竞争能力不同,拥有锁的线程在使用完后又会立即拿到锁,重新买票,导致其他线程都阻塞在加锁函数里。
这种情况的解决办法就是让阻塞的线程都排好队,新到的线程排到队列的最后面,按顺序获得锁。拥有锁的线程在使用完后不要立马去申请,而是自动排到队列最后面

同步:保证数据安全的情况下,让线程访问资源具有一定的顺序性

保证同步的一种方法就是条件变量

条件变量

概念

当一个线程互斥的访问某个变量时,它可能发现在其他线程改变状态前,神恶魔也做不了
例如一个线程访问队列时,发现队列为空,只能等待,直到其他线程将一个节点添加到队列中,这种情况就需要用到条件变量
在这里插入图片描述

当线程申请锁失败就到这个队列里排着,这样队列里就有一堆按顺序排的线程,新的线程也按这个过程。当拥有锁的线程使用完归还锁后,先敲一下铃铛,然后排到队列最后。铃铛被敲后唤醒队列中的线程申请使用锁。这个铃铛这部分就是条件变量。根据上面情形,条件变量必须依赖于锁的使用。os对这两个锁和条件变量结构也需要维护

为什么需要互斥量

条件等待是线程间同步的一种手段,如果只有一个线程,条件不满足,一直等下去都不会满足,所以必须要有一个线程通过某些操作,改变共享变量,使原先不满足的条件变得满足,并且友好的通知等待在条件变量上的线程
条件不会无缘无故的突然满足,必然牵扯到共享数据的变化。所以一定要用互斥锁来保护,没有互斥锁就无法安全的获取和修改共享数据

在这里插入图片描述
由于解锁和等待不是原子的,调用解锁之后,wait之前,如果已经有其他线程获取到互斥量,掘弃条件满足,发送了信号,那么wait将错过这个信号,可能导致线程永远阻塞在wait,所以解锁和等待必须是原子操作

wait进入函数后,回去查看条件变量等于0吗,等于就把互斥量变为1,直到wait返回,把条件变量改为1,把互斥量恢复为原样

条件变量使用规范

等待条件代码

pthread_mutex_lock(&mutex);
while (条件为假)
pthread_cond_wait(cond, mutex);
修改条件
pthread_mutex_unlock(&mutex);

给条件发送信号代码

pthread_mutex_lock(&mutex);
设置条件为真
pthread_cond_signal(cond);
pthread_mutex_unlock(&mutex);

同步概念和竞态条件

同步:在保证数据安全的前提下,让线程能够按照某种特定的顺序访问临界资源,从而有效避免饥饿问题,叫同步
竞态条件:因为时序问题,导致程序异常,称之为竞态条件

条件变量初始化

int pthread_cond_init(pthread_cond_t *restrict cond,const pthread_condattr_t *restrict attr);
参数:
cond:要初始化的条件变量
attr:NULL

在这里插入图片描述

销毁

int pthread_cond_destroy(pthread_cond_t *cond)

等待条件满足

int pthread_cond_wait(pthread_cond_t *restrict cond,pthread_mutex_t *restrict mutex);
参数:
cond:要在这个条件变量上等待
mutex:互斥量,后面详细解释

唤醒

int pthread_cond_broadcast(pthread_cond_t *cond); //全部
int pthread_cond_signal(pthread_cond_t *cond); //一个

条件变量和锁的使用类似,都可以局部和全局定义,全局则不需要初始化和销毁

案例

五个线程对cnt变量加加,用锁和条件变量保证线程安全和顺序性

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <iostream>int cnt = 0;
pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
void *count(void *num)
{uint64_t i = (uint64_t)num;while (true){pthread_mutex_lock(&lock);pthread_cond_wait(&cond, &lock);printf("线程 %d cnt:%d\n", i, cnt++);pthread_mutex_unlock(&lock);}
}int main()
{//64位整形,强转指针for (uint64_t i = 0; i < 5; i++){pthread_t tid;//不能取i的地址传入,线程里访问的和这里的i会是同一个变量,//一个修改,另一个读取错误pthread_create(&tid, nullptr, count, (void*)i);//usleep(13);}sleep(3);while (true){//pthread_cond_signal(&cond);pthread_cond_broadcast(&cond);printf("唤醒\n");sleep(1);}return 0;
}

在这里插入图片描述

我们怎么知道一个线程需要休眠?一定是临界资源不就绪时,临界资源也是有状态的,而临界资源有没有就绪时判断出来的。判断也是访问临界资源的过程,所以注定了休眠时在加锁和解锁之间。条件变量的等待函数会自动释放锁,所以必须在申请和释放锁中间

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

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

相关文章

如何使用提示测试为LLMs构建单元测试?

原文地址&#xff1a;how-to-build-unit-tests-for-llms-using-prompt-testing 确保您的人工智能交付&#xff1a;快速测试完美生成应用程序的基本指南 2024 年 4 月 26 日 如果你曾经编写过软件&#xff0c;你就会知道测试是开发过程中必不可少的一部分。特别是单元测试&#…

设计模式——保护性暂停

同步模式之保护性暂停 文章目录 同步模式之保护性暂停定义实现应用带超时版 GuardedObject扩展——原理之join扩展——多任务版 GuardedObject 定义 即 Guarded Suspension&#xff0c;用在一个线程等待另一个线程的执行结果 要点 有一个结果需要从一个线程传递到另一个线程&…

【Linux】进程的控制①之进程创建与进程退出

目录 ​编辑 一 、进程的创建 1、fork函数 2.函数的返回值 ①return 可以返回两次&#xff0c;使得父子进程读到的id有两个值 ②写实拷贝&#xff0c;使得父子进程读到的值都对自身有意义 a.为什么要写实拷贝&#xff0c;而不是在创建子进程的时候直接就将空间给子进程开辟好&a…

Linux系统安装Redis7(详细版)

Linux系统安装Redis7 一、windows安装redis二、Linux安装Redis下载redis编辑redis7.conf文件启动redis-server服务如何关闭redis服务设置Redis开机自启动 一、windows安装redis Window 下安装 下载地址&#xff1a;https://github.com/dmajkic/redis/downloads 下载到的Redi…

【Qt之·控件·样式表】

系列文章目录 文章目录 前言一、Qt样式表的基础知识1.1 Qt样式表的定义和语法规则1.2 Qt样式表中的选择器和属性1.2.1 盒子模型1.2.2 border 1.3 Qt样式表中的伪类和伪元素 二、编写基本的Qt样式表2.1 在Qt应用程序中引入样式表文件的方式2.2 设置基本的背景色、字体样式等 三、…

MATLAB中功率谱密度计算pwelch函数使用详解

MATLAB中功率谱密度计算pwelch函数使用详解 目录 前言 一、pwelch函数简介 二、pwelch函数参数说明 三、pxx pwelch(x)示例 四、[pxx,f]pwelch(x,window,noverlap,nfft,fs)示例 四、[pxx,f] pwelch(x,window,noverlap,nfft,fs,freqrange,spectrumtype)示例 五、多通道功…

SpringCloud整合Gateway结合Nacos

目录 一、引入依赖 二、开启两个测试项目 2.1 order service ​编辑 2.2 user service 三、gateway项目 3.1 新建一个bootstrap.yml文件 3.2 将我们的的网关配置写道nacos里的配置里 3.3 测试&#xff1a;看能够根据网关路由到两个测试的项目 四、 优化 4.1 将项目打包…

低代码技术在构建质量管理系统中的应用与优势

引言 在当今快节奏的商业环境中&#xff0c;高效的质量管理系统对于组织的成功至关重要。质量管理系统帮助组织确保产品或服务符合客户的期望、符合法规标准&#xff0c;并持续改进以满足不断变化的需求。与此同时&#xff0c;随着技术的不断进步&#xff0c;低代码技术作为一…

Windows系统启动Redis

一、下载windows版本Redis 1.1 选择一个使用的版本 在以下地址中选择一个Windows系统可以使用的版本 https://github.com/microsoftarchive/redis/tags 1.2 下载 1.3 解压到文件夹 二、启动Redis 双击redis-server.exe启动Redis 出现以下界面即启动成功 三、测试是否可以使…

hive-row_number() 和 rank() 和 dense_rank()

row_number() 是无脑排序 rank() 是相同的值排名相同&#xff0c;相同值之后的排名会继续加&#xff0c;是我们正常认知的排名&#xff0c;比如学生成绩。 dense_rank()也是相同的值排名相同&#xff0c;接下来的排名不会加。不会占据排名的坑位。

DB-GPT部署验证

一、DB-GPT简介 DB-GPT是一个开源的数据库领域大模型框架。目的是构建大模型领域的基础设施&#xff0c;通过开发多模型管理、Text2SQL效果优化、RAG框架以及优化、Multi-Agents框架协作等多种技术能力&#xff0c;让围绕数据库构建大模型应用更简单&#xff0c;更方便。 GITHU…

R语言4版本安装mvstats(纯新手)

首先下载mvstats.R文件 下载mvstats.R文件点此链接&#xff1a;https://download.csdn.net/download/m0_62110645/89251535 第一种方法 找到mvstats.R的文件安装位置&#xff08;R语言的工作路径&#xff09; getwd() 将mvstats.R保存到工作路径 在R中输入命令 source(&qu…

分享我的github仓库

这是一个由现代C编写的小型、学习性质的服务器框架&#xff0c;包含压缩&#xff0c;序列化&#xff0c;IO调度&#xff0c;Socket封装&#xff0c;文件配置&#xff0c;日志库等多个完整自研模块&#xff0c;欢迎到我的仓库阅读代码和安装体验&#xff0c;期待任何的建议和反馈…

Themis新篇章:老牌衍生品协议登陆Blast L2,探索全新经济模型

本文将深入分析 Themis 的最新经济模型&#xff0c;探讨其核心概念和机制、优势与创新之处、风险与挑战。 一、引言 随着区块链技术的不断发展&#xff0c;DeFi 衍生品项目逐渐成为市场的焦点。而用户体验的革新&#xff0c;进一步的金融创新&#xff0c;去中心化治理方案的优…

Linux开发板 FTP 服务器移植与搭建

VSFTPD&#xff08;Very Secure FTP Daemon&#xff09;是一个安全、稳定且快速的FTP服务器软件&#xff0c;广泛用于Unix和Linux操作系统。它以其轻量级、高效和易于配置而受到赞誉。VSFTPD不仅支持标准的FTP命令和操作&#xff0c;还提供了额外的安全特性&#xff0c;如匿名F…

Python爬取豆瓣电影Top250数据

任务 爬取豆瓣电影top250中的影片名称、影片海报、年份、地区、类型、评分、评价人数、总体评价&#xff0c;并输出到douban_top250.xlsx文件中 环境 Python 3.8 requests bs4 openpyxl 源码 # 创建一个新的Excel工作簿 workbook openpyxl.Workbook() # 获取默认的工作表…

软件工程全过程性文档(软件全套文档整理)

软件项目相关全套精华资料包获取方式①&#xff1a;进主页。 获取方式②&#xff1a;本文末个人名片直接获取。 在软件开发的全过程中&#xff0c;文档是记录项目进展、决策、设计和测试结果的重要工具。以下是一个简要的软件全过程性文档梳理清单&#xff1a; 需求分析阶段…

“Unite“ > MacOS下很不错的网站转应用App的工具

前言 前不久在浏览mac论坛&#xff0c;无意了解到一款非常好的工具&#xff0c;可以将网站转换为app&#xff0c;考虑到我们现在的主要应用都从本地客户端转成web形式使用&#xff0c;但基于本能的使用习惯&#xff0c;还是希望有个快捷的访问信息&#xff0c;这个应用非常适合…

集成框架 -- OSS

前言 接入oss必须有这两个文档基础 使用STS临时访问凭证访问OSS_对象存储(OSS)-阿里云帮助中心 前端上传跨域 正文 sts前后端通用&#xff0c;开通图示 AliyunSTSAssumeRoleAccess 后端实现代码 public static void main(String[] args) {String regionId "cn-ha…

java-函数式编程-函数对象

定义 什么是合格的函数&#xff1f;无论多少次执行函数&#xff0c;只要输入一样&#xff0c;输出就不会改变 对象方法的简写 其实在类中&#xff0c;我们很多参数中都有一个this&#xff0c;被隐藏传入了 函数也可以作为对象传递&#xff0c;lambda就是很好的例子 函数式接口中…