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

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



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的实际应用和创新。🌐🔍

相关文章
|
1月前
|
算法 Linux 调度
深入理解Linux操作系统的进程管理
本文旨在探讨Linux操作系统中的进程管理机制,包括进程的创建、执行、调度和终止等环节。通过对Linux内核中相关模块的分析,揭示其高效的进程管理策略,为开发者提供优化程序性能和资源利用率的参考。
70 1
|
2月前
|
算法 调度 Python
深入理解操作系统中的进程调度算法
在操作系统中,进程调度是核心任务之一,它决定了哪个进程将获得CPU的使用权。本文通过浅显易懂的语言和生动的比喻,带领读者了解进程调度算法的重要性及其工作原理,同时提供代码示例帮助理解。
|
1月前
|
调度 开发者 Python
深入浅出操作系统:进程与线程的奥秘
在数字世界的底层,操作系统扮演着不可或缺的角色。它如同一位高效的管家,协调和控制着计算机硬件与软件资源。本文将拨开迷雾,深入探索操作系统中两个核心概念——进程与线程。我们将从它们的诞生谈起,逐步剖析它们的本质、区别以及如何影响我们日常使用的应用程序性能。通过简单的比喻,我们将理解这些看似抽象的概念,并学会如何在编程实践中高效利用进程与线程。准备好跟随我一起,揭开操作系统的神秘面纱,让我们的代码运行得更加流畅吧!
|
1天前
|
监控 搜索推荐 开发工具
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
2025年1月9日更新Windows操作系统个人使用-禁用掉一下一些不必要的服务-关闭占用资源的进程-禁用服务提升系统运行速度-让电脑不再卡顿-优雅草央千澈-长期更新
|
1月前
|
C语言 开发者 内存技术
探索操作系统核心:从进程管理到内存分配
本文将深入探讨操作系统的两大核心功能——进程管理和内存分配。通过直观的代码示例,我们将了解如何在操作系统中实现这些基本功能,以及它们如何影响系统性能和稳定性。文章旨在为读者提供一个清晰的操作系统内部工作机制视角,同时强调理解和掌握这些概念对于任何软件开发人员的重要性。
|
1月前
|
Linux 调度 C语言
深入理解操作系统:从进程管理到内存优化
本文旨在为读者提供一次深入浅出的操作系统之旅,从进程管理的基本概念出发,逐步探索到内存管理的高级技巧。我们将通过实际代码示例,揭示操作系统如何高效地调度和优化资源,确保系统稳定运行。无论你是初学者还是有一定基础的开发者,这篇文章都将为你打开一扇了解操作系统深层工作原理的大门。
|
1月前
|
存储 算法 调度
深入理解操作系统:进程调度的奥秘
在数字世界的心脏跳动着的是操作系统,它如同一个无形的指挥官,协调着每一个程序和进程。本文将揭开操作系统中进程调度的神秘面纱,带你领略时间片轮转、优先级调度等策略背后的智慧。从理论到实践,我们将一起探索如何通过代码示例来模拟简单的进程调度,从而更深刻地理解这一核心机制。准备好跟随我的步伐,一起走进操作系统的世界吧!
|
1月前
|
算法 调度 开发者
深入理解操作系统:进程与线程的管理
在数字世界的复杂编织中,操作系统如同一位精明的指挥家,协调着每一个音符的奏响。本篇文章将带领读者穿越操作系统的幕后,探索进程与线程管理的奥秘。从进程的诞生到线程的舞蹈,我们将一起见证这场微观世界的华丽变奏。通过深入浅出的解释和生动的比喻,本文旨在揭示操作系统如何高效地处理多任务,确保系统的稳定性和效率。让我们一起跟随代码的步伐,走进操作系统的内心世界。
|
1月前
|
运维 监控 Linux
Linux操作系统的守护进程与服务管理深度剖析####
本文作为一篇技术性文章,旨在深入探讨Linux操作系统中守护进程与服务管理的机制、工具及实践策略。不同于传统的摘要概述,本文将以“守护进程的生命周期”为核心线索,串联起Linux服务管理的各个方面,从守护进程的定义与特性出发,逐步深入到Systemd的工作原理、服务单元文件编写、服务状态管理以及故障排查技巧,为读者呈现一幅Linux服务管理的全景图。 ####
|
2月前
|
算法 Linux 调度
深入浅出操作系统的进程管理
本文通过浅显易懂的语言,向读者介绍了操作系统中一个核心概念——进程管理。我们将从进程的定义出发,逐步深入到进程的创建、调度、同步以及终止等关键环节,并穿插代码示例来直观展示进程管理的实现。文章旨在帮助初学者构建起对操作系统进程管理机制的初步认识,同时为有一定基础的读者提供温故知新的契机。