《操作系统》的同步、通信与死锁

基础概念

同步

进程互斥:若干进程因相互争夺独占型资源而产生的竞争关系,具有唯一排它性,互斥无法限制访问者对资源的访问顺序,即访问是无序的。

进程同步:我们把异步环境下的一组并发进程因直接制约而互相发送消息而进行互相合作、互相等待,使得各进程按一定的速度执行的过程称为进程间的同步

同步:体现的是一种协作性。互斥:体现的是排它性

通信

进程通信就是指进程间的信息交换,交换信息可以使一个状态,也可以是很多的 byte。

死锁

当某进程提出资源申请后,使得系统中一些进程处于无休止的阻塞状态,在无外力作用下,永远不能再继续前进。

进程同步

临界区: 进程中访问临界资源的一段需要互斥执行的代码,任何时刻只允许一个进程在这其中执行。

进入区: 检查可否进入临界区的一段代码,如可进入,设置相应”正在访问临界区“标志

退出区: 清除"正在访问临界区"标志

剩余区: 代码中的其余部分

进程间通信

为什么进程间要进行通信

  • 数据传输:一个进程需要将它的数据发送给另一个进程。
  • 资源共享:多个进程间共享同样的资源。
  • 通知事件:一个进程需要向另一个或一组进程发送消息。通知它们发送了某种事件。
  • 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另一个进程的所有操作,并能够及时知道它的状态改变。

进程间的通信方式

每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须通过内核,在内核中开辟一块缓冲区,进程 1 把数据从用户空间拷到内核缓冲区,进程 2 再从内核缓冲区把数据读走,内核提供的这种机制称为进程间通信

1、直接通信

自动建立链路 一条链路

恰好对应一对通信进程

每对进程之间恰好只有一个链接存在

链接可以是单向的,但通常是双向的

2、间接通信

通过操作系统维护的消息队列实现进程间的消息接收和发送

  • 每个消息队列都有唯一的标识
  • 只有共享了相同消息队列的进程才能够通信

通信链路的属性 

  • 只有共享了相同消息队列的进程,才建立连接;
  • 连接可以是单向或双向
  • 消息队列可以与多个进程相关联

通信流程

  • 创建新的消息队列
  • 通过消息队列发送和接收消息
  • 销毁消息队列

3、低级通信

进程间同步互斥也存在信息的交换,因此也属于是一种 IPC。1、通信的数据量太少;2、通信对用户不透明

4、高级通信机制

信号(signal)通信机制:信号是一种比较复杂的通信方式,用于通知接收进程某个事件已经发生。只能发送单个信号而不能传送数据。

管道通信

        机制匿名管道:管道是一种半双工的通信方式,数据只能单向流动,需要双向通信时需要建立起两个管道;而且只能在具有亲缘关系的进程间(父子进程关系)通信。

        命名管道(FIFO):FIFO 是一种先进先出的队列。它类似于一个管道,只允许数据的单向流动。每个FIFO 都有一个名字,允许不相关的进程访问同一个 FIFO。

消息传递通信机制:消息队列是由消息的链表,存放在内核中并由消息队列标识符标识。有足够权限的进程可以向队列中添加消息,被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。

信号量通信机制:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。

共享内存通信机制:共享内存就是映射一段能被其他进程所访问的内存,这段共享内存由一个进程创建,但多个进程都可以访问。共享内存是最快的 IPC 方式,它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制,如信号两,配合使用,来实现进程间的同步和通信。

套接字通信机制:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。

信号通信机制

1、当用户按某些键时,产生信号;

2、硬件异常产生信号,这些情况通常由硬件检测到;

3、进程用kill函数将信号发送给另一个进程;

4、用户可用kill命令将信号发送给其它进程。

不足:传送信息量小,只有一个信号类型。开销太大,发送进程需要调用系统调用,这时核心会中断接收进程,且要管理它的堆栈、调用处理程序、恢复被中断的接收信号进程等。另外信号的数量受到限制,并且只能传送有限的信息量,例如不能携带参数等,所以对于复杂的通信操作不适用。

管道通信机制 

1、管道是半双工的,数据只能向一个方向流动;进程不知道管道的另一端;

需要双方通信时,需要建立起两个管道;

2、只能在具有公共祖先的两个进程之间使用;

3、一个进程向管道中写的内容被管道另一端的进程读出。写入的内容每次都添加在管道缓冲区的末尾,并且每次都是从缓冲区的头部读出数据。如果读进程不读走管道缓冲区中的数据,那么写操作将阻塞。

4、管道内部提供了同步机制

命名管道

命名管道 (NamedPipe) 是服务器进程和一个或多个客户进程之间通信的单向或双向管道。不同于匿名管道的是:命名管道可以在不相关的进程之间和不同计算机之间使用,服务器建立命名管道时给它指定一个名字,任何进程都可以通过该名字打开管道的另一端,根据给定的权限和服务器进程通信。

消息传递通信机制

消息队列实际上就是一个链表,而消息就是链表中具有特定格式和优先级的记录,对消息队列有写权限的进程可以根据一定规则在消息链表中添加消息,对消息队列有读权限的进程则可以从消息队列中获得所需的信息。

在发送数据时,会分成一个一个独立的数据单元,也就是消息体(数据块),消息体是用户自定义的数据类型,消息的发送方和接收方要约定好消息体的数据类型,所以每个消息体都是固定大小的存储块,不像管道是无格式的字节流数据。消息队列生命周期随内核,如果没有释放消息队列或者没有关闭操作系统,消息队列会一直存在,而前面提到的匿名管道的生命周期,是随进程的创建而建立,随进程的结束而销毁。

与命名管道相比,消息队列的优势在于

1、消息队列可以独立于发送和接收进程而存在,从而消除了在同步命名管道的打开和关闭时可能产生的困难。

2、同时通过发送消息还可以避免命名管道的同步和阻塞问题,不需要由进程自己来提供同步方法。

3、接收程序可以通过消息类型有选择地接收数据,而不是像命名管道中那样,只能默认地接收。

缺点:一是通信不及时,二是附件也有大小限制

信号量通信机制

信号量:相当一个信号灯,表示状态,在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。

为了防止出现因多个程序同时访问一个共享资源而引发的一系列问题,我们需要一种方法,它可以通过生成并使用令牌来授权,在任一时刻只能有一个执行线程访问代码的临界区域。而信号量就可以提供这样的一种访问机制,让一个临界区同一时间只有一个线程在访问它,也就是说信号量是用来协调进程对共享资源的访问的。

P(sv):如果 sv 的值大于零,就给它减 1(将信号量S的值减1,即S=S-1);如果S>=0,则该进程继续执行;否则该进程置为等待状态,排入等待队列。就挂起该进程的执行;

V(sv):如果有其他进程因等待 sv 而被挂起,就让它恢复运行;如果没有进程因等待 sv 而挂起,就给它加 1(将信号量S的值加1,即S=S+1)。如果S>0,则该进程继续执行;否则释放队列中第一个等待信号量的进程。

共享内存通信机制

共享内存是把同一个物理内存区域同时映射到多个进程的内存地址空间的通信机制。共享内存是在两个正在运行的进程之间共享和传递数据的一种最有效的方式,不同进程之间共享的内存通常安排为同一段物理内存。

优点:采用共享内存通信的一个显而易见的好处是效率高,因为进程可以直接读写内存,而不需要任何数据的拷贝。

套接字通信机制

Socket 通信,不仅仅是一台主机上的两个进程可以进行通信,还可以让处在因特网中的两个进程进行通信。例如 管道、消息队列、共享内存、信号量和信号都是在同一台主机上进行进程间通信,那要想跨网络与不同主机上的进程之间通信,就需要Socket 通信

死锁

死锁:当某进程提出资源申请后,使得系统中一些进程处于无休止的阻塞状态,在无外力作用下,永远不能再继续前进。

 根本原因:资源有限且操作不当。

产生死锁的必要条件

1、互斥条件:某段时间内某资源只能由一个进程使用。

2、占有和等待条件:进程因请求资源而阻塞时,对已分配给它的资源保持不放。

3、不剥夺条件:资源在未使用完前,不能被剥夺,由使用进程释放。

4、循环等待条件:发生死锁时,有向图必构成一环路。

死锁的处理方法

死锁防止:破坏四个条件
死锁避免:银行家算法
死锁的检测和恢复:死锁检测算法

死锁防止:

1、互斥:将互斥的共享资源封装成可以同时访问

2、持有并等待:进程请求资源时,要求他不持有任何其他资源(必须一次性申请自己需要所有的资源,但资源利用率低)

3、非抢占:如进程请求不能立即分配的资源,就释放自己已经占有的资源

4、循环等待:对资源排序,要求进程按顺序请求资源, 使用资源有序分配法,来破环环路等待条件。 

死锁检测算法

1、允许系统进入死锁状态

2、维护系统的资源分配图

3、定期调用死锁检测算法来搜索图中是否存在死锁

4、出现死锁时,用死锁恢复机制进行恢复

5、死锁检测算法的使用:

6、死锁多久可能会发生?多少进程需要回滚

7、进程终止:终止所有的死锁进程,一次终止一个进程直到死锁消除

8、终止顺序:进程的优先级;进程已经运行的时间和还需运行的时间;进程已占用的资源;进程完成需要的资源

银行家算法

银行家算法是一个避免死锁产生的算法。以银行借贷分配策略为基础,判断并保证系统处于安全状态

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

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

相关文章

二叉树的中序遍历

题目描述 现有一棵n个结点的二叉树(结点编号为从0到n-1,根结点为0号结点),求这棵二叉树的中序遍历序列。 输入描述 第一行一个整数n​​​​​​​​(1≤n≤50​​​​​​​​​​​),表示二…

Docker容器Docker桌面配置镜像加速

打开Docker Desktop应用程序,点击设置 具体配置如下: {"builder": {"gc": {"defaultKeepStorage": "20GB","enabled": true}},"experimental": false,"features": {"buil…

编译Linux内核并修改版本号后缀为学号-Ubuntu22.04中编译安装Linux内核6.7.8

前言:实验课要求下载最新版本Linux内核并修改版本号,本人在Vmware中Ubuntu22.04中实现,花三天时间查阅大量网站资料。记录一下误打误撞成功的过程,希望对你们有帮助。 目录 一、常规安装步骤&猜想Ubuntu与gcc版本过低 二、安…

202003 青少年软件编程(Scratch)等级考试试卷(一级)

202003 青少年软件编程(Scratch)等级考试试卷(一级) 第1题:【 单选题】 在Scratch中,以下哪个区域可以展示编程效果? A:代码区 B:舞台区 C:角色区 D:积木区 【正确答案】: B 【试题解析】…

基于PySide2实现调用本地摄像头抓拍并保存照片(Python版本)

因为横向课题需要,这是其中的一个小小的功能,单独拎出来作为一个小demo,方便后续学习使用 项目实现功能: 点击open按钮,摄像头开启,实时捕获周围图像并显示 点击capture按钮,保存摄像头照片&am…

日期工具的逻辑与数据请求函数的完善

src\libs\utils.js 获取当前日期格式 /*** 获取当前日期格式* param {*} field * returns */ function getNowDate(field) {const date new Date()let year date.getFullYear(),month date.getMonth() 1,day date.getDate()switch (field) {case day:return ${year}-${mo…

02- 使用Docker安装RabbitMQ

使用Docker安装RabbitMQ 下载安装镜像 方式一: 启动docker服务,然后在线拉取 # 在线拉取镜像 docker pull rabbitmq:3-management# 使用docker images查看是否已经成功拉取方式二: 从本地加载 ,将RabbitMQ上传到虚拟机中后使用命令加载镜像即可 docker load -i mq.tar启动M…

leetcode 第388场周赛第二题

这道题其实和第一题是很相似的,也是一种贪心的算法(话说这周怎么都是贪心和暴力) 简单来说就是对于happiness的数组进行排序,用一个变量记录就行了。 思路:对于数组从大到小排序,然后对于happiness[i]-i进…

LLM实施的五个阶段

原文地址:Five Stages Of LLM Implementation 大型语言模型显着提高了对话式人工智能系统的能力,实现了更自然和上下文感知的交互。这导致各个行业越来越多地采用人工智能驱动的聊天机器人和虚拟助手。 2024 年 2 月 20 日 介绍 从LLMs的市场采用情况可以…

【C++】每日一题 92 反转链表

给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 class ListNode { public:int val;ListNode* next;ListNode(int _val) {val _val;next nullptr;} };…

AcWing 1211. 蚂蚁感冒

Problem: AcWing 1211. 蚂蚁感冒 文章目录 思路解题方法复杂度Code 思路 这是一个模拟题。题目的意思是&#xff0c;如果一只蚂蚁感冒了&#xff0c;那么它会把感冒传给所有和它相向而行的蚂蚁。所以我们只需要找出所有和第一只蚂蚁相向而行的蚂蚁就可以了。具体来说&#xff0…

vue中的性能优化

Vue.js 性能优化是提高应用性能和用户体验的关键之一。以下是一些常见的 Vue.js 性能优化方法&#xff1a; 使用 Vue Devtools 进行性能分析&#xff1a; Vue Devtools 是一个强大的浏览器扩展&#xff0c;可以帮助开发者实时监测 Vue 应用的性能指标、组件状态和数据流&#x…

LabelImg:一个简单易用的图像标注工具

目录 LabelImg是什么&#xff1f; 如何使用LabelImg进行图像标注&#xff1f; LabelImg的优势和应用场景 在哪里下载它 随着人工智能技术的不断发展&#xff0c;机器学习和深度学习在图像识别、目标检测等领域中得到了广泛的应用。而要训练一个有效的模型&#xff0c;通常需…

Vue3+ts(day02:CompositionAPI、setup)

学习源码可以看我的个人前端学习笔记 (github.com):qdxzw/frontlearningNotes 觉得有帮助的同学&#xff0c;可以点心心支持一下哈&#xff08;笔记是根据b站上学习的尚硅谷的前端视频【张天禹老师】&#xff0c;记录一下学习笔记&#xff0c;用于自己复盘&#xff0c;有需要学…

备忘录怎么导出数据 备忘录数据导出方法

在忙碌的生活中&#xff0c;我时常依赖于备忘录来记录重要的信息&#xff0c;从工作截止日期到生活琐事&#xff0c;无一不靠它来帮我分担记忆的压力。但随着时间的推移&#xff0c;我发现有时候我不仅仅需要在软件内查看这些信息&#xff0c;还需要将它们导出&#xff0c;或许…

【数据库】软件测试之MySQL数据库练习题目

有表如下&#xff1a; Student 学生表 SC 成绩表 Course 课程表 Teacher 老师表 每个学生可以学习多门课程&#xff0c;每一个课程都有得分&#xff0c;每一门课程都有老师来教&#xff0c;一个老师可以教多个学生 1、查询姓‘朱’的学生名单 select * from Student whe…

【深度学习笔记】优化算法——Adam算法

Adam算法 &#x1f3f7;sec_adam 本章我们已经学习了许多有效优化的技术。 在本节讨论之前&#xff0c;我们先详细回顾一下这些技术&#xff1a; 在 :numref:sec_sgd中&#xff0c;我们学习了&#xff1a;随机梯度下降在解决优化问题时比梯度下降更有效。在 :numref:sec_min…

Docker创建openresty容器

1.拉取最新images docker pull openresty/openresty:latest 2.创建简单容器 docker run -itd --restartunless-stopped \--name openresty \-p 80:80 \openresty/openresty:latest 3.创建成功后将重要配置文件从容器中复制出来&#xff0c;方便后续挂载。/data/docker/open…

力扣--动态规划5.最长回文子串

class Solution { public:string longestPalindrome(string s) {// 获取输入字符串的长度int n s.size();// 如果字符串长度为1&#xff0c;直接返回原字符串&#xff0c;因为任何单个字符都是回文串if (n 1)return s;// 创建一个二维数组dp&#xff0c;用于记录子串是否为回…

React-路由小知识

1.默认路由 说明&#xff1a;当访问的是一级路由时&#xff0c;默认的二级路由组件可以得到渲染&#xff0c;只需要在二级路由的位置去掉path,设置index.属性为true。 2.404路由 说明&#xff1a;当浏览器输入ul的路径在整个路由配置中都找不到对应的pth,为了用户体验&#x…