操作系统基础:进程同步【中】

简介: 操作系统基础:进程同步【中】



1 进程同步(中)

1.1 信号量机制

1.1.1 总览

1.1.2 什么是信号量机制

1.1.2.1 什么是信号量

1.1.2.2 什么是原语

1.1.2.3 “一对原语” 指的是什么

1.1.2.4 什么是信号量机制

既然信号量可以是多种类型,自然而然的我们就想到要去探讨这些不同的类型。

1.1.3 整型信号量

1.1.3.1 解释

它与一般的整型变量的区别在于,它只有初始化、P操作、V操作三种操作

1.1.3.2 实现过程

1.1.3.3 缺点

假如进程一直得不到资源,那么它就会一直占用处理机。

1.1.4 记录型信号量

1.1.4.1 解释

1.1.4.2 信号量的定义

1.1.4.3 PV操作的定义

1.1.4.4 实例

假设有四个进程都想使用打印机,如图。且打印机的数量S为2台

(1)P0最先执行,先执行wait,它会将S-1,并转入使用打印机的代码。接着,P1执行,先执行wait,它也会将S-1,并转入使用打印机的代码

(2)P2执行wait时先将S-1,此时S<0,为-1。故P2执行BLOCK原语,将自己加入阻塞队列。P3的执行过程与P2类似。此时,S=-2,阻塞队列中有2个进程

(3)P0执行打印机完毕,它会执行Signal,将S+1,此时S=-1,执行Wakeup原语唤醒阻塞队列,于是最先进入队列的P2开始使用打印机。接着,P2执行打印机完毕,它会执行Signal,将S+1,此时S=0,执行WakeUp唤醒阻塞队列,于是队列最前的P3开始使用后打印机。

(4)最终,P1使用打印机完毕,它会执行Signal,将S+1,此时S=1,无须执行wakeUp。接着P3使用打印机完毕,执行SIgnal将S+1,此时S=2,无须执行WakeUp。

1.1.4.5 特征

PV操作上是一种低级的进程通信原语,它是不可以被中断的。

1.1.5 总结

1.2 信号量实现进程互斥、同步、前驱关系

1.2.1 总览

1.2.2 信号量实现进程互斥

1.2.2.1 步骤

注意:划分临界区指的是分析哪些资源应该被划分为临界资源(比如打印机的使用、摄像头的使用)

1.2.2.2 信号量的数据结构

1.2.2.3 mutex的具体实现过程

1.2.2.4 实现互斥的逻辑

Mutex相当于一个访问临界资源S的名额。进程在试图访问一个临界资源时,首先执行P操作,将S-1,假如此时S<0,说明此时S没有名额访问,进程将自己加入阻塞队列;假如S>=0,说明S可以访问。进程执行V操作将S+1,假如此时S<=0,说明阻塞队列中有进程在等待访问资源,执行唤醒操作。

1.2.2.5 注意点

1.2.3 信号量实现就进程同步

1.2.3.1 什么是进程同步问题?

1.2.3.2 实现的步骤

(1)假设P1的②必须在P2的④之前执行。如图

(2)使S的值初始为0

关于S的理解:

(3)描述

1.2.4 信号量机制实现前驱关系

1.2.4.1 什么是前驱关系

如图,里面包含了很多前驱关系,比如S1->S2,S1->S3,S2->S4…

1.2.4.2 解决思路

结合之前实现进程同步的思路,在前面执行的进程必须有该种资源的V操作,在后面执行的进程必须有该种资源的P操作,资源的初始值设为0。

由于不同的前驱关系相互不会造成影响,所以每一种前驱关系都对应一种不同的临界资源,

3. 具体实现

1.2.5 总结

1.3 生产者-消费者问题

1.3.1 PV问题的分析思路

1.3.2 问题描述

示意图如下:

1.3.3 问题分析

1.3.3.1 关系分析(确定有哪些)

题目中一共有3个进程,分别为生产者生产进程,消费者消费进程,访问缓冲区的进程。

他们的同步互斥关系为

(1)只有当缓冲区不满时,生产者才可以生产

(2)只有当缓冲区不空时,消费者才可以消费

(3)同一时间只可以有单独的对象访问缓冲区

1.3.3.2 整理思路(确定PV操作的大致顺序)

因为有三个同步互斥关系,可以设置三种资源。

(1)缓冲区不满的资源:Empty

(2)缓冲区不空的资源:Full

(3)缓冲区的资源:Mutex

它们的关系如图:

1.3.3.3 设置信号量

初始时,缓冲空间内没有物品,为空。且缓冲空间没有被访问,为1

Empty,初始为n(同步信号量)

Full,初始为0(同步信号量)

Mutex,初始为1(互斥信号量)

1.3.4 代码实现

1.3.4.1 关于生产者

生产者在生产之前需要先申请一个空位置(Empty-1),对应Empty的P操纵。之后需要申请缓冲空间的使用(Mutex-1),对应Mutex的P操作。之后先进行Mutex的V操作,释放缓冲区的资源。可以思考,生产者会不会执行V(Empty)呢?答案是不会,因为生产者肯定不会使资源减少,它在生产之后会使Full+1,对应Full的V操作。

1.3.4.2 关于消费者

消费者在消费之前需要先申请一个资源(Full-1),对应Full的P操作。之后需要申请缓冲空间的使用(Mutex-1),对应Mutex的P操作。之后先进行Mutex的V操作,是否缓冲区的资源。可以思考,生产者会不会执行V(Full)呢?答案是不会,因为消费者肯定不会使资源增加,它在消费之后会使Empty+1,对应Empty的V操作。

1.3.4.3 关键代码

While(1)表示生产者会一直不断的生产、消费者会一直不断地消费

1.3.5 能否改变相邻P、V操作的步骤

1. 改变相邻P操作的顺序

对于生产者,假如它会先申请Mutex,再申请消耗一个空闲区;对于消费者,它会先申请Mutex,再申请消耗一个Full空间。那么,假如此时Empty=0,Full为n,那么生产者会进入睡眠,等待消费者消耗产品并将其唤醒;而消费者发现Mutex没有多余,所以它会等待生产者使用完Mutex将其唤醒。此时二者相互等待对方的唤醒,进入了死锁。

可以看出,不可以改变相邻P操作

2. 改变相邻V操作的顺序

对于生产者,先执行V(Full)再执行V(Mutex)都是起到释放资源的作用,不会造成死锁。对于消费者同理。

3. 将生产者生产资源的过程加到PV操作之间逻辑上并不会造成死锁,但是这样会造成进程访问临界资源的时间过长,不利于系统的稳定。对于消费者同理。

1.3.6 总结

只可以生产一种产品的单生产者

1.4 多消费者-多生产者问题

1.4.1 PV问题的分析思路

1.4.2 问题描述

解释:多个生产者生产不同类别的产品,多个消费者消费不同类别的产品,存储空间的容量有限

示意图:

1.4.3 问题分析

1.4.3.1 关系分析(确定同步互斥关系)

(1)进程

共有四个进程

父亲生产苹果、母亲生产橘子、女儿消费苹果、儿子消费橘子

(2)同步关系

①只有当盘子中有苹果时,女儿才消费苹果

②只有当盘子中有橘子时,儿子才消费橘子

③只有当盘子中没有水果时,父亲、母亲才生产

(3)互斥关系

四个进程对盘子的访问必须是互斥的

1.4.3.2 整理思路(确定PV操作顺序)

因为有四种同步互斥关系,因此必须设置四个临界资源

(1)苹果资源:Apple

(2)橘子资源:Orange

(3)盘子资源:Mutex

(4)盘子容量资源:Plate

它们的关系如图

1.4.3.3 设置信号量

初始时Apple、Orange都没有,为0,Plate中没有水果,初值为n,没有进程访问盘子,Mutex初值为1。

1.4.4 代码

1. 对于生产者1(父亲)

生产者1首先会申请一个盘子的容量,执行P(Plate),将Plate-1,接着会占用存储空间,执行P(Mutex),将Mutex-1。接着将苹果放入盘子,执行V(Apple),使Apple+1,假如此时Apple<=0,说明此时有消费者在排队消费,会执行WakeUp,唤醒消费者(女儿)进行消费。最后会释放占用的存储空间,执行V(Mutex)。

对于生产者2(母亲)也是类似的操作。

2. 对于消费者(女儿)

消费者1首先会申请减少一个Apple的容量,执行P(Apple-1),将Apple-1。接着,消费者1会申请占用存储空间,执行P(Mutex),使Mutex-1。最后女儿从盘子中取出苹果。接着执行V(Plate)操作,将容量+1,假如此时Plate<=0,说明有生产者在等待,执行唤醒语句,唤醒等待队列中第一个生产者。最后会释放存储空间,执行V(Mutex)。

对于消费者2(儿子)也是类似的操作。

3. 关键代码

4. 改进

因为盘子的容量为1,所以同一时刻最多只有一个进程可以进入盘子,达到了互斥访问的目的。因此当Plate=1时,Mutex可以省略不写。

试想,当盘子容量为2且没有互斥信号量Mutex时,父亲与母亲都可以在同一时间访问盘子,可能会造成错误。

1.4.5 总结

只可以生产一种产品的多生产者

一个重要的注意点:

🕮 2 总结

操作系统,如默默守护的守夜者,无声地管理硬件与软件的交流,为计算机创造和谐秩序。

它是无形的引导者,让复杂的任务变得井然有序,为用户提供无忧体验。

操作系统的巧妙设计,让计算机变得更加智能高效,让人与科技之间的交流更加顺畅。

在每一次启动中,它如信任的伙伴,带领我们进入数字世界的奇妙旅程。

渴望挑战操作系统的学习路径和掌握进阶技术?不妨点击下方链接,一同探讨更多操作系统的奇迹吧。我们推出了引领趋势的💻OS专栏:《OS从基础到进阶》 ,旨在深度探索OS的实际应用和创新。🌐🔍

相关文章
|
16天前
|
存储 调度 C++
【操作系统】进程与线程的区别及总结(非常非常重要,面试必考题,其它文章可以不看,但这篇文章最后的总结你必须要看,满满的全是干货......)
【操作系统】进程与线程的区别及总结(非常非常重要,面试必考题,其它文章可以不看,但这篇文章最后的总结你必须要看,满满的全是干货......)
45 1
|
1月前
|
算法 数据库
操作系统:经典进程同步问题的高级探讨
操作系统:经典进程同步问题的高级探讨
31 1
|
6天前
|
存储 安全 Linux
深入理解操作系统:从进程管理到内存分配
【6月更文挑战第30天】在数字时代的心脏,操作系统是现代计算不可或缺的组成部分。本文将深入探讨操作系统的核心功能,包括进程管理、内存分配以及文件系统管理。我们将通过实际案例分析,揭示这些机制如何在提高计算机性能的同时保证资源的有效利用。文章旨在为读者提供对操作系统工作原理的深刻理解,并展示其在现代技术中的应用价值。
|
10天前
|
机器学习/深度学习 算法 调度
操作系统中的进程调度策略
【6月更文挑战第26天】本文将深入探讨操作系统中的核心组件之一——进程调度。我们将从进程调度的基本概念入手,分析其重要性以及如何影响系统性能。文章将介绍几种常见的进程调度算法,并通过实例展示它们在实际操作系统中的应用。我们还将讨论现代操作系统中进程调度面临的挑战和未来可能的发展方向。
|
13天前
|
存储 缓存 算法
深入理解操作系统:从进程管理到内存优化
【6月更文挑战第23天】在数字化时代,操作系统是支撑计算设备的心脏。本文将探索操作系统的核心组件,着重于进程管理和内存优化策略,揭示它们如何共同确保系统资源的高效利用和任务的顺畅执行。通过分析现代操作系统的设计哲学和技术实现,本文旨在为读者提供对操作系统内部工作原理的深刻洞察,并展示其对提高计算性能和用户体验的重要性。
|
16天前
|
存储 负载均衡 算法
深入理解操作系统的进程调度
【6月更文挑战第20天】本文将探讨操作系统中的进程调度,包括其定义、重要性以及常见的调度算法。我们将通过具体的例子和代码片段来深入理解进程调度的工作原理和实现方式。最后,我们将讨论进程调度在现代操作系统中的应用和挑战。
|
20天前
|
数据挖掘 调度 开发者
Python并发编程的艺术:掌握线程、进程与协程的同步技巧
并发编程在Python中涵盖线程、进程和协程,用于优化IO操作和响应速度。`threading`模块支持线程,`multiprocessing`处理进程,而`asyncio`则用于协程。线程通过Lock和Condition Objects同步,进程使用Queue和Pipe通信。协程利用异步事件循环避免上下文切换。了解并发模型及同步技术是提升Python应用性能的关键。
42 5
|
18天前
|
调度
操作系统之进程调度机制
操作系统之进程调度机制
16 1
|
18天前
|
存储 缓存 运维
深入理解操作系统:从进程管理到内存分配
在数字时代的心脏,操作系统扮演着至关重要的角色。本文将深入探讨操作系统的核心机制,包括进程管理、内存分配和文件系统,揭示它们如何协同工作以支持现代计算需求。通过技术深度解析和实际应用示例,我们将一窥操作系统的复杂性与优雅,理解其在软件开发和系统性能优化中的重要性。
|
19天前
|
负载均衡 算法 调度
深入理解操作系统之进程调度
本文旨在探究操作系统核心机制之一——进程调度。文章首先概述进程与线程的基本概念,随后详细解析进程调度的目标、常见算法及其优缺点,并探讨现代操作系统中进程调度的高级话题,如多核调度和实时系统的调度策略。通过实例分析,本篇文章将帮助读者深化对进程调度复杂性的理解,并指出未来可能的发展方向。