进程的组成
程序段、数据段和PCB
PCB(和管理有关)
本质:和进程管理有关的都存放在PCB中,程序本身运行所需数据在程序段和数据段中
进程的特征(与程序的区别)
小结(进程的定义、组成、组织方式、特征)
进程的状态与转换(五状态模型)
三种基本状态:运行态、就绪态(万事俱备、只欠CPU)、阻塞态
创建态(新建态)、终止态(结束态)
进程状态小结
进程控制(实现进程状态的转换)(原语)
进程控制示意图
进程控制相关原语(创建,终止,阻塞及唤醒原语)
进程通信
共享存储
消息传递
管道通信
没写满不允许读,没读空不允许写
线程
同一个进程被分为多个线程,增加并发度。
程序执行流的最小单位,轻量级进程
线程的属性
同一进程内的线程切换,不会引起进程切换
不同进程中的线程切换,会引起进程切换
线程的实现方式(用户级线程、内核级线程)
用户级线程:从用户角度可以看到的线程,对操作系统来说用户级线程是透明的
(同理内核级线程)
重点:操作系统只看得见内核级线程,因此只有内核级线程才是处理机分配的单位
重点:操作系统只看得见内核级线程,因此只有内核级线程才是处理机分配的单位
多线程模型
多对一:多个用户级线程映射到一个内核级线程(开销小)(易阻塞)
一对一:一个用户级线程映射到一个内核级线程(并发能力强)(线程管理成本高开销大)
多对多:n映射到m(n大于等于m)(克服上述二者缺点)
线程概念和多线程小结
调度
同时有很多事情要处理,需要确定某种规则来决定处理任务的顺序
处理机调度:进程数量大于处理机数量,那么从就绪队列中按照一定的算法选择一个进程并将处理机分配给他运行,以实现进程的并发执行
高中低级调度
高级调度(作业调度)
高级调度(作业调度):按照一定的原则从外存上处于后备队列的作业中挑选(一个或多个)作业,为其分配内存资源并建立相应进程(建立PCB)
中级调度(内存调度)
中级调度(内存调度):决定将哪个处于刮起状态的进程重新调入内存。(引入了虚拟存储技术后,可将暂时不能运行的进程调至外存等待,即调出的进程处于挂起状态)
低级调度(进程调度)
三层调度的联系对比总结
进程的七状态模型(包含两种挂起态)
挂起和阻塞的区别
挂起态是进程映像调到外存,阻塞态是进程映像还在内存中
(处理机)调度的回顾总结
进程调度的时机
进程调度的方式
进程的切换与过程
注意区分广义和狭义上的进程调度
进程切换是有代价的,物极必反,不是越频繁越好,效率降低
进程调度,切换与过程、方式的小结
调度算法评价指标
CPU利用率
系统吞吐量
周转时间,带权周转时间(必然大于等于1),越小越好
等待时间
调度算法(一)
先来先服务(FCFS,First Come First Serve)
即按照到达的先后顺序调度,事实上等待时间越久的越优先得到服务
对于短进程来说体验不好,如奶茶店买奶茶,你买一杯,前面的人买20杯
短作业优先(SJF)
分为非抢占式短作业优先和抢占式短作业优先
即每次调度时选择当前已到达且运行时间最短的作业/进程
FCFS和SJF两种算法对比
高响应比优先(HRRN)
同时考虑了进程的等待时间和要求服务时间
HRRN是非抢占式,只有进程主动放弃CPU时,才需要进行调度
三种调度算法总结
调度算法(二)(适用于交互式系统)
时间片轮转(RR,Round Robin)
注意:
1.时间片不能太大:如果时间片太大,该算法退化为先来先服务算法,并且会增大进程响应时间
2.时间片太小,进程切换过于频繁,效率低(一般来说,设计时间片要让切换进程的开销占比不超过1%)
对于那些时间片到达但是还没执行完的进程,会进入就绪队列依次排队等待继续执行
当进程执行完但时间片还没用完时,该进程会主动放弃处理机,发生调度
例题:时间片大小为2
优先级调度算法
分为抢占式优先级调度算法和非抢占式优先级调度算法
就绪队列可能不唯一;优先级可分为静态(创建进程时确定,之后不变)和动态(有初始值,并后来不断调整)
非抢占式优先级调度算法
抢占式优先级调度算法
优先级调度算法补充
多级反馈队列调度算法(对所有算法的折中权衡)
例题:
调度算法(二)三种算法总结
进程同步与进程互斥
进程同步(直接制约关系)
进程同步:要让各并发进程按要求有序地推进(因为进程的异步性导致两个进程交替推进的次序是不确定的)
个人理解:为了解决进程并发运行带来的异步问题,为了实现某些应用需求,必须协调某些进程的工作次序
举例:
要实现女一号和女二号想法的需求,则必须有指令先后顺序的需求,才能实现想法
进程互斥(访问临界资源,间接制约关系)
第二个想访问临界资源的进程必须等第一个访问临界资源的进程结束并释放该资源后,第二个进程才可以访问
进入(上锁),访问,退出(解锁),其他操作
进程同步与互斥小结
进程互斥的软硬件实现方法(结合代码)(没看)
信号量机制
解决进程互斥,进程同步的问题
分为整型信号量和记录型信号量
信号量:一个变量,表示系统中某种资源的数量
原语:此处的wait(s)申请资源可记为P(s) 和 signal(s)可记为V(s)释放资源原语用于操作信号量
wait(s) signal(s)相当于两个函数,s相当于参数,通过s加一或减一的结果,记录系统中某个可用资源(如打印机的数量),如果没有可用的则进程进入等待队列
整型信号量
记录型信号量
整型信号量和记录型信号量小结(PV操作)
信号量实现进程互斥、同步和前驱关系
mutex, mutex1, mutex2相当于自己设的3个信号量(变量),如记录打印机,摄像头等资源
进程互斥的信号量可以设初值为1(即临界资源只可同时给1个进程使用)
信号量实现进程同步(信号量初始值设为0)
下图中右侧文字的两种情况都可以实现预期功能(即代码4一定在代码2后执行)
信号量机制实现前驱关系(复杂的同步关系)
信号量实现进程同步、互斥前驱关系的小结
经典进程同步互斥问题
生产者-消费者问题
生产者消费者问题代码实现
多生产者-多消费者问题(多指多类)
多类生产者生产的产品和消费者消费的产品,而不是多个
例子:
儿子或女儿会触发一个事件(使盘子为空),才允许父亲或母亲向盘子里放水果
实现:
吸烟者问题
读者写者问题
写进程和任何其他进程(包括读进程和写进程)都互斥两个读进程可以
读写一起:可能读进程读到的并不是自己想读的进程(而是写进程新写的进程)
两个写:数据覆盖
rw:read 和 write
多个读进程读的时候,第一个读进程要进行加锁操作(防止写进程干扰),之后的读进程则直接读即可(不用再加锁),读工作结束后最后一个读进程要执行解锁操作
存在的问题:
哲学家就餐问题(解决进程死锁)
每个哲学家进程需要同时持有两个临界资源(左右两边的筷子),才能开始吃饭
管程(类似于 类,封装的思想)
是用来实现进程的互斥和同步的
为了避免因为使用信号量机制编写程序困难易出错的问题(不用再关注复杂的PV操作),而引入了管程——一种高级同步机制
编译器负责互斥的进入管程中的过程(即相当于调用类中的各个操作缓冲区产品的函数)如下图中的insert和remove函数
管程小结
死锁
死锁、饥饿、死循环的区别
死锁产生的必要条件
什么时候会发生死锁
总之,对不可剥夺资源的不合理分配,可能导致死锁
死锁小结
循环等待未必死锁,死锁一定有循环等待
死锁的处理策略(预防、避免和检测解除)
死锁的处理策略——预防死锁
1.破坏互斥条件(很多时候无法使用此方法)(SPOOLING技术)
2.
3.
4.破坏循环等待条件
死锁的处理策略——避免死锁(安全序列,不安全状态)
安全序列
银行家算法
最大需求,已分配,最多还需要
(可以逐个进程分配资源,只要不死锁即可)
银行家算法代码实现
死锁的处理策略——检测和解除(资源分配图)
死锁检测算法:依次消除与不阻塞进程相连的边,直到无边可消
绿色边表示之前已经分配出去的,此时再看剩下的资源还是否满足蓝色边的申请。
如果某一个进程P1或P2已经执行完,则可以将与该节点相连的所有边都划掉