进程的定义、特征、组成、组织
进程的定义
PCB 是进程控制块(Process Control Block)的缩写,它是操作系统中用于管理进程的重要数据结构。
进程的组成
进程的组织
链接方式:
索引方式:
进程的特征
本章内容小结:
进程的状态与转换
进程的状态
三种基本状态:
另外两种状态:
创建态:
结束态:
进程状态的转换
本章小结:
进程控制
什么是进程控制
进程控制过程
如何实现进程控制
进程控制相关的原语
本章回顾:
进程通信
什么是系统资源?
系统资源包括:
CPU: 中央处理器,用于执行程序和指令。CPU 时间是一种重要的系统资源。
内存:用于临时存储程序和数据。内存空间是一种关键的系统资源。
存储空间:硬盘空间、固态硬盘空间等,用于永久存储程序和数据。存储空间也是一种重要的系统资源。
网络带宽:用于网络通信的带宽,它决定了网络通信的速度和吞吐量。网络带宽也属于一种系统资源。
文件描述符:用于表示打开的文件和网络连接。文件描述符也是一种系统资源。
信号量:用于实现进程间同步和互斥,从而协调对共享资源的访问。信号量也属于一种系统资源。
套接字:用于实现网络通信的端点。每个网络连接都需要消耗一个套接字,所以套接字也是一种系统资源。
总之,系统资源就是操作系统用于运行程序和维持系统运行所需要的各种有限的硬件或软件手段。合理分配和管理这些系统资源是操作系统的一项关键职责。
共享存储
共享一块大家都可以访问的空间,一次只能有一个进程进行读或写操作
管道通信
半双工通信是一种通信模式,它只允许在两个通信方向上有一个方向上的通信。也就是说,在任何给定的时间,只能有一方发送数据,另一方接收数据。发送方和接收方角色是固定的,不会发生转换。这与全双工通信形成对比,全双工通信支持双向同时传输.
消息传递
发送信息的进程将消息头写好,接受信息进程根据消息头读取信息或寻找信封是哪一个
本章总结:
线程概念和多线程模型
为什么要引入线程?什么是线程?
引入线程机制后的变化
线程的属性
线程的实现方式
线程的实现方式有两种:
用户级线程
内核级线程
多线程模型
多线程模型分为三种:
多对一
一对一
多对多
本章总结:
处理机调度的概念及层次
调度的基本概念
调度的三个层次
高级调度
外存是一个广义的概念,它包括所有非CPU直接访问的长期存储设备。例如机械硬盘、固态硬盘是外存常见的形式。
中级调度
低级调度
进程的挂起状态与七状态模型
挂起和阻塞的主要区别在于:
挂起通常由内核主动进行切换,阻塞通常由进程自己发出请求主动进入。
挂起需要其他进程显式唤醒,阻塞可以自动解除。
挂起释放CPU也保存上下文,阻塞也释放CPU但保留上下文。
挂起后的进程不会自动调度,阻塞后的进程可以自动调度。
挂起不依赖事件的完成,阻塞依赖某事件(如IO)的完成。
挂起和阻塞都是导致进程离开运行状态的机制,但前者更加主动,后者更加被动;前者需要外界显式唤醒,后者可以自行解除。这两个状态的区分为操作系统进行进程调度与同步提供了更加详细的依据。
本章总结
进程调度的时机、切换与过程、方式
进程调度的时机
简而言之:
内核程序临界区和临界区要区别开来。内核程序临界区的锁如果不尽快释放会影响到操作系统中的其他工作,所以说在内核程序临界区不能进行进程调度,否则锁会长时间被持有而不会被释放。
这个地方打印机属于系统资源,很明显是一个临界资源,如果当前进程一直不调度的话,那么CPU啥事都干不了就等着打印,这显然是不合理的。并且打印机属于普通的临界资源,不会影响操作系统的内核管理工作。
进程调度的方式
进程的切换与过程
本章内容小结:
调度算法的评价指标
CPU利用率
系统吞吐量
周转时间
这里时间中的减号表示这个时间段,并不是表示两个时间的值相减。
等待时间
响应时间
本章总结:
调度算法
作业调度和进程调度是操作系统进行CPU调度的两种不同层次。它们的主要区别在于:
作业调度(高级调度):
也称为长作业调度或高级调度。它决定哪些作业(进程)被加载到内存中以备执行。
作业调度运行较不频繁,通常只在作业创建和终止时进行运行。
它主要根据作业的优先级、内存要求、CPU时间限制等因素进行调度。
目的在于优化系统的全局吞吐量和响应时间。
进程调度(低级调度):
也称为短作业调度或中级调度。它决定哪个进程在CPU上运行,以及运行多长时间。
进程调度运行非常频繁,通常每隔几十到几百毫秒就运行一次。
它主要根据进程优先级、进程状态、调度算法、时间片等因素进行调度。
目的是提高CPU利用率,确保每个进程都能得到公平的执行机会。
所以,作业调度和进程调度的主要区别在于:
作业调度的时间范围更长,典型作业执行时间为秒至分钟。而进程调度的时间范围更短,典型为毫秒至秒级。
作业调度更关注系统整体吞吐量,而进程调度更侧重CPU利用率和公平性。
作业调度的调度频率较低,进程调度的调度频率较高。
作业调度选择执行哪些作业,而进程调度选择执行哪个进程和执行多长时间。
作业与进程的概念范围不同,作业调度范围更广。
作业调度和进程调度都是操作系统进行CPU资源分配的手段,但在时间范围、目标和调度粒度上有较大差异。作业调度侧重长期全局的资源分配,而进程调度侧重短期CPU利用的优化。这两种调度相互配合,共同完成操作系统的CPU管理与调度功能。
先来先服务—FCFS
短作业优先—SJF
这是非抢占式的:
而如果使用的是抢占式的:
高响应比优先—HRRN
小结:
时间片轮转—RR
时间片大小为2的情况:
时间片大小为5的情况:
可能出现的问题,比如与FCFS对比:
优先级调度算法
非抢占式:
抢占式:
多级反馈队列调度算法
内容小结:
进程的同步与互斥
内容小结:
进程互斥的软件实现办法
单标志法
双标志先检查法
双标志后检查法
Peterson算法
内容小结:
进程互斥的硬件实现方法
中断屏蔽方法
也就是说中断指令互斥的作用范围仅限于单个处理机
TestAndSet指令
执行TSL指令时,它的内部运转逻辑:
假设lock现在为false,代表临界资源A空闲,那么我就可以访问这个资源,同时将lock=true,提醒别的进程,这个临界资源A我正在使用,让他们等等
假设lock为true,代表临界资源正在有人使用,所以我必须等待,并且将lock=true,并不影响什么,所以没关系,只是为了让lock为false时可以上锁,将上锁与检查在一个TSL指令完成。
Swap指令
old是每个进程都要进行的一步,都必须将old=true
因为lock是某一特定临界资源的共享变量,当每一个进程准备访问这个特定的临界资源时,初始化old=true,然后进入while循环进行交换,如果当前lock是false,则交换后old=false,则当前进程可以跳出循环进入临界区代码段,同时因为交换,lock=old=true上锁,不让别的进程来打扰,别的进程会因为lock变为true,一直在while循环等待,当我使用完临界资源,则将lock=false,此时别的进程再交换old和lock就能判断old=false,可以跳出循环,使用临界资源。
内容小结:
信号量机制
信号量机制存在的意义
什么是信号量机制
整型信号量
记录型信号量
如果value小于等于0说明还有其他的进程需要这个资源,所以我们使用wakeup原语将等待队列的第一个进程唤醒。
注意:
在使用打印机时,进程占用CPU并执行打印机资源的读取、写入以及其他控制操作,也就是处于运行态。
在等待使用打印机处于阻塞态
我们来看一个例子:
最后我们整体梳理一下:
总结一下:
用信号量机制实现进程互斥、同步、前驱关系
信号量机制实现进程互斥
信号量机制实现进程同步
信号量机制实现前驱关系
前驱关系(Precedence Relationship)是项目管理中的一个重要概念。它描述了项目中任务之间的相互依赖关系,表明某个任务的开始/完成依赖于其他任务的开始/完成。
我们总结一下:
关于锁:
锁这个东西我们并不陌生,比如说在Java中我们的synchronized,Redisson中的分布式锁他们都是互斥锁。而互斥锁有一个特点那就是他会使用一个多方可见的结构,通过结构的两阶段变化,从而满足相应条件达到互斥的约束效果。我们前面使用信号量机制实现线程互斥,就类似于互斥锁的底层实现。不信的话我们还可以看看如下的例子:
java中synchronized底层原理就是判断monitor中的monitor是否有值(两阶段)
Redisson中分布式锁的底层原理就是使用SETNX命令,看返回的是0还是1(两阶段)
在操作系统中使用信号量来完成互斥,看信号量的值是0还是1
而使用信号量机制实现进程同步关系其实就与锁的关系不大了。这一点其实在我们使用的时候就可以体现出来。在使用信号量机制实现线程互斥的时候P、V原语在代码块中一定是成对出现的,而在实现进程同步关系的时候我们发现P、V原语可以在代码块中独立出现。此时我们可以简单的理解为:
P是前提条件的减法
V是前提条件的加法
只要前提条件还有,就可以往下执行,从而实现同步
操作系统的NB之处就在于使用相同的代码、不同的调用完成了两种不同的功能。
进程同步与互斥经典问题
生产者消费问题
问题描述
系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。
生产者、消费者共享一个初始为空、大小为n的缓冲区。
只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。
只有缓冲区不空时,消费者才能从中取出产品,否则必须等待。
缓冲区是临界资源,各进程必须互斥地访问。
问题分析
关系分析。生产者和消费者对缓冲区访问是互斥关系,同时生产者和消费者又是一个相互协作的关系,只有生产者生产之后,消费者才能消费,它们也是同步关系。
整理思路。根据各进程的操作流程确定P、V操作的大致顺序。
生产者每次要消耗(P)一个空闲缓冲区,并生产(V)一个产品。
消费者每次要消耗(P)一个产品,并释放一个空闲缓冲区(V)。
往缓冲区放入/取走产品需要互斥。
信号量设置。设置需要的信号量,并根据题目条件确定信号量初值。( 互斥信号量初值一般为1,同步信号量的初始值要看对应资源的初始值是多少)
这个地方我们的思路是这样的:
生产者只有在有空闲位置的时候才能生产一个商品,那么我们设置一个同步信号量就是空闲位置,只有在这个信号量不为0的时候,生产者才能进行生产,如此来达到同步的效果
消费者只有在有产品的时候才能消费,那么我们就再设置一个同步信号量产品数量,只有在这个信号量不为0的时候,消费者才能进行消费,如此来达到同步的效果
实现
总结
多生产者-多消费者问题
问题描述
问题分析
实现方法①有mutex
实现方法②无mutex
为什么有mutex和没有mutex一样呢?
原因在于:本题中的缓冲区大小为1,在任何时刻,apple、 orange、 plate 三个同步信号量中最多只有一个是1。因此在任何时刻,最多只有一个进程的P操作不会被阻塞,并顺利地进入临界区…
并且不需要担心dad和mom线程同时访问,导致plate成为负值的情况。只是因为出现这种的原因是读操作和写操作分成了两步,不具有原子性,而这里读和写都在原语中,而原语是可以保证原子性的。
实现方法③如果有两个盘子plate
总结
吸烟者问题
问题描述
问题分析
实现方法
总结
读者-写者问题
问题描述
问题分析
实现方法①给count加mutex互斥访问
这里说一下为什么要加mutex。
比如:当count=0时,第一个读者进程执行到p(rw),rw=0,假设此时时间片到了,切换到第二个读者进程,第二个进程发现count=0,则执行p(rw),但是此时rw=0,于是第二个进程被堵在p(rw)这里,同理,后面的可能会有多个进程堵在p(rw),只有当第一个进程再次获得时间片,执行count++,让count不为0,然后其他进程就可以直接绕过if直接进行count++来访问文件,但是第三个读者进程和后面的几个可能堵在p(rw)的多个读者进程则必须得等count–为0后才可以再次和写进程竞争来访问文件,对count的访问没有做到一气呵成,会导致本来一些进程一直堵在p(rw)。
实现方法②加一个w实现“读写公平法”
在上面的算法中,读进程是优先的,即当存在读进程时,写操作将被延迟,且只要有 一个读进程活跃,随后而来的读进程都将被允许访问文件。这样的方式会导致写进程可能长时间等待,且存在写进程“饿死”的情况。
若希望写进程优先,即当有读进程正在读共享文件时,有写进程请求访问,这时应禁止后续读进程的请求,等到已在共享文件的读进程执行完毕,立即让写进程执行,只有在无写进程执行的情况下才允许读进程再次运行。为此,增加一个信号量并在上面程序的writer()和 reader()函数中各增加一对PV操作,就可以得到写进程优先的解决程序。
总结
哲学家进餐问题
问题描述
问题分析
实现方法
总结
管程
为什么引入管程
管程的定义和基本特征
管程实现生产者消费者问题
java中类似于管程的机制
总结一下:
死锁
什么是死锁
死锁、饥饿、死循环的区别
死锁产生的四个必要条件
什么时候会发生死锁?
死锁的处理策略
预防死锁
破坏互斥条件
破坏不可剥夺条件
破坏请求和保持条件
破坏循环等待条件
避免死锁
什么是安全序列?
安全序列、安全状态、不安全状态、死锁之间的联系
避免系统进入不安全状态------银行家算法
使用代码实现
死锁的检测和解除
死锁的检测
举个例子,可以消除所有边,即无死锁发生
举个例子,不可消除所有边,即产生死锁
死锁的解除
————————————————
版权声明:本文为CSDN博主「十八岁讨厌编程」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zyb18507175502/article/details/129012143