基于本人观看学习 哈工大李治军老师主讲的操作系统课程 所做的笔记,仅进行交流分享。
特此鸣谢李治军老师,操作系统的神作!
如果本篇笔记帮助到了你,还请点赞 关注 支持一下 ♡>𖥦<)!!
主页专栏有更多,如有疑问欢迎大家指正讨论,共同进步!
给大家跳段街舞感谢支持!ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ ዽ ጿ ኈ ቼ
第二章 进程与线程(下)
第二章 进程与线程(上):【操作系统】学习笔记:第二章 进程与线程 (上)【哈工大李治军老师】
更多操作系统笔记:【哈工大李治军老师】操作系统笔记专栏汇总
如果有需要markdown或者PDF可以私信我,可以在此基础上自己添加补充笔记(●’◡’●)
进程与线程(下) 目录
- 第二章 进程与线程(下)
- 课程链接:
- 一、CPU调度策略
- 1.多进程图像与CPU调度
- 2.如何设计调度算法
- 3.先到先服务FCFS
- 4.短作业优先SJF
- 5.提高响应速度——时间片轮转法RR
- 响应时间和周转时间同时存在,怎么办?
- 二、一个实际的schedule函数
- 优先级动态调整
- counter作用总结
- 三、进程同步与信号量
- 1.进程合作:多进程共同完成一个任务
- 2.信号量
- 3.P V操作
- 四、信号量临界区保护
- 1.竞争
- 2.临界区
- 3.轮换法
- 4.标记法
- 5.Peterson算法
- 6.面包店算法
- 关中断
- 硬件原子指令法
- 五、信号量的代码实现
- sleep_on:
- 六、死锁处理
课程链接:
b站: 【哈工大】操作系统 李治军(全32讲)
大学MOOC:大学慕课—操作系统—主讲:哈工大李治军
一、CPU调度策略
1.多进程图像与CPU调度
当PID:1执行结束/阻塞,切换到其他进程去执行
此时2、3都在就绪队列中,应该选择谁执行?——这就是调度策略
例: 两种进程调度策略
调度策略问题很难穷尽,我们研究的就是对一个实际的系统面对这些任务应该如何设计调度算法
2.如何设计调度算法
面对进程:CPU调度的目标应该是进程满意
核心:时间复杂度小,执行速度尽量快
关键问题:操作系统在CPU调度中,需要折中,需要综合
IO约束型任务:需要大量的输入和输出操作,例如从磁盘读取或写入大量数据、向网络发送请求等。这些操作需要较长时间完成,CPU 的使用率较低,因此这种任务的瓶颈通常在于 IO 操作的速度。解决这种任务的方法通常是使用异步 IO 操作,以便在等待 IO 操作完成时释放 CPU 资源。
CPU约束型任务:这种任务通常需要大量的计算,并且需要快速完成,例如图像处理、视频编码、加密解密等。这些操作需要大量的 CPU 时间,因此 CPU 的使用率较高,而 IO 操作通常只是一个辅助操作。解决这种任务的方法是使用多线程或分布式计算,利用多个 CPU 核心同时进行计算,提高计算速度。
3.先到先服务FCFS
平均周转时间即作业从进入系统到完成的时间,完成时间减去到达时间再除以任务个数
计算公式:平均周转时间 = (作业完成时间 - 作业提交时间)/ 作业数
其中,作业完成时间指作业执行完毕的时刻,作业提交时间指作业进入系统的时刻
周转时间越短,系统的效率就越高
4.短作业优先SJF
5.提高响应速度——时间片轮转法RR
RR算法采用抢占式调度,即每个进程被分配一个时间片,当时间片用完后,该进程会被挂起并放回就绪队列,等待下一次调度。同时,RR算法会按照就绪队列中进程的顺序依次调度每个进程。这样,每个进程都能够在一定程度上得到公平的CPU时间,避免了某些进程长时间占用CPU的情况,提高了系统的响应速度和吞吐量。 注意合理设置时间片大小
无论是否执行完一个进程,每次都执行一个时间片,切换下一个时间片执行其他进程
响应时间和周转时间同时存在,怎么办?
Word很关心响应时间,而gcc更关心周转时间,两类任务同时存在怎么办?
一个调度算法让多种类型的任务同时都满意,怎么办?
如果前台任务绝对优先: 会造成饥饿
因此需要对优先级进行动态调整,而后台任务往往响应时间很长
此时应该后台任务执行一段时间,优先级下降,释放出cpu,让前台任务再次执行
既要以轮转调度为核心,又要在轮转调度的基础上增加一些优先级,前台任务与后台任务协调
二、一个实际的schedule函数
优先级动态调整
counter既作为优先级,又作为时间片,只需要维护一个counter变量
counter作用总结
三、进程同步与信号量
1.进程合作:多进程共同完成一个任务
对多个进程的推进需要有合理有序的约束
司机需要等待售票员发出信号:
实例:生产者–消费者
2.信号量
只发信号还不能解决全部问题,单靠counter代表缓冲区空闲的个数还不够,还需要知道有多少个进程在sleep,使用信号量 记录一些更多的信息
使用信号量来表达更丰富的信息,是一个计数器,可以控制对共享资源的访问量
除了睡眠和唤醒,还需要记录其他信息: 量
记录有多少个进程在sleep:1 -> 2 -> 1 -> 0
还有一个空闲缓冲区:
P和C可以根据信号量可以实现进程同步!
如果信号量为负数,-几代表有几个进程在等待
如果信号量为正数,代表有几个资源可以使用
3.P V操作
P:消费资源 减
V:产生资源 加
当缓冲区为空:
多个生产者和多个消费者共享缓冲区。生产者将数据项写入缓冲区中,而消费者则从缓冲区中读取数据项。
计数器 empty用于表示缓冲区中还有多少空闲,full 表示有多少缓冲区已被占用。使用了一个互斥信号量mutex,保证同时只有一个进程能够修改缓冲区的内容。
当生产者要向缓冲区中写入数据时,首先要尝试获取空闲缓冲区的数量(也就是执行 P(empty) 操作)。如果目前empty为 0,则说明缓冲区已满,生产者需要等待某个消费者释放后才能继续写入数据(也就是进入阻塞状态)。
如果目前有空闲缓冲区,则使用互斥信号量(即执行 P(mutex)),将数据写入缓冲区中,
释放互斥信号量(互斥锁)之后,通知消费者此时缓冲区已经有数据可消费(即执行 V(full) 操作),以便消费者读取缓冲区中的数据
当消费者要从缓冲区中读取数据时,首先尝试获取空闲缓冲区的数量(也就是执行 P(full) 操作)。如果目前已经full为 0,则说明缓冲区为空,消费者需要等待某个生产者写入数据后才能继续读取数据(也就是进入阻塞状态)。
如果有已经被写入数据的单元格,则使用互斥信号量(即执行 P(mutex)),将数据从缓冲区中读取出来
消费者将读取的数据项打印出来之后,释放互斥锁并通知生产者目前缓冲区中有空闲的单元格,以便生产者继续写入数据(即执行 V(empty) 操作)。
四、信号量临界区保护
1.竞争
由于共享数据没有保护,造成数据竞争问题:
解决竞争条件的直观想法:上锁
2.临界区
临界区(Critical Section):一次只允许一个进程进入的该进程的那一段代码
保护共享数据——信号量
临界区代码的保护原则
基本原则:
1.互斥进入:如果一个进程在临界区中执行,则其他进程不允许进入
这些进程间的约束关系称为互斥(mutual exclusion)
这保证了是临界区
好的临界区保护原则
2.有空让进:若干进程要求进入空闲临界区时,应尽快使一进程进入临界区
3.有限等待::从进程发出进入请求到允许进入不能无限等待
3.轮换法
每个进程被赋予一个次序号(也称时间片)
所有进程按照次序号依次排队。执行上下文切换时,当前进程将释放 CPU 时间,并将接下来 CPU 时间分配给下一个进程
当某个进程需要访问共享资源(也就是进入临界区)时,它首先要等待一定长度的时间,直到轮到它使用该资源为止
这样,即使多个进程尝试同时进入共享资源,也能够以轮流使用的方式完成。
4.标记法
标记法的flag是 boolean 类型,初始值为 false。当一个进程想要进入临界区时,它首先要获取这个标记变量,并将其设置为 true,表示自己已经进入了临界区。此时,如果有其他进程想要进入临界区,就必须等待当前进程退出临界区并释放这个标记变量。
进程在退出临界区之后,需要将这个标记变量重新设置为 false,以便其他进程可以使用它。如果同时有多个进程试图获取这个标记变量并将其设置为 true,就会出现数据竞争的问题,因此标记法通常要和其它同步机制(如信号量、互斥锁)一起使用。
标记法过度使用可能会导致系统性能下降,因为每个进程都必须轮流尝试获取临界区标志,而这种轮流获取的过程可能导致等待时间过长
可能会导致缓冲区空闲但进程AB都不会执行,因此需要规定名字
5.Peterson算法
Peterson算法通过在临界区的代码中让两个进程轮流执行,保证了不会同时进入临界区的情况。
当其中一个进程想要进入临界区时,另一个进程必须等待,直到当前进程完成临界区的操作并释放它的资源后才能进入,从而避免了死锁和数据竞争问题
Peterson算法维护了两个bool型的变量 turn 和 flag,分别表示当前轮到哪个进程进入临界区,和每个进程是否想要进入临界区:
i的flag为true,表示它想要进入临界区。然后进入 while 循环中进行判断,检查另一个进程 j是否也想要进入临界区,如果 flag[j] 为 true 并且轮到 j 进入临界区(即 turn==j),进程 i 就需要等待。一旦它获得了进入临界区的机会,就可以执行相应操作,并将自己的标志设置为 false,这样进程 j 就可以进入临界区。
6.面包店算法
仍然是标记和轮转的结合
如何轮转: 每个进程都获得一个序号,序号最小的进入
如何标记: 进程离开时序号为0,不为0的序号即标记
面包店: 每个进入商店的客户都获得一个号码,号码最小的先得到服务;号码相同时,名字靠前的先服务
互斥进入: P在临界区内,P试图进入,一定有(num[i],i)<(num[k],k),P循环等待。
有空让进: 如果没有进程在临界区中,最小序号的进程一定能够进入。
有限等待: 离开临界区的进程再次进入一定排在最后(FIFO),所以任一个想进入进程至多等n个进程
关中断
关中断是指在处理器上禁止中断响应,以防止其他进程或线程干扰当前正在执行的进程或线程。
当一个进程或线程需要获取共享资源时,它可以通过关闭中断来确保自己在操作期间不会被中断。
在操作完成之后,它再重新打开中断,使其他进程或线程可以获取和使用共享资源。该机制是基于硬件实现的,并且只能在处理器级别上操作
但是当多个处理器时,关中断无法影响其他处理器中的进程,一个处理器关闭了中断,其他处理器还可以继续运行他们的进程或线程。
硬件原子指令法
硬件原子指令法提供了一组原子性的操作指令,可以在一个确保操作不会被中断的环境下,原子地执行某个操作,避免数据竞争和死锁等问题
五、信号量的代码实现
Semaphore值是否大于0,如果不是,则将自身设为阻塞状态并加入相应的等待队列中,最后调用schedule()函数切换到其他进程或线程来运行。而在sti()指令中断后,Semaphore已经被占用,防止了其他进程或线程的访问。
启动磁盘读以后睡眠,等待磁盘读完由磁盘中断将其唤醒,也是一种同步
sleep_on:
sleep_on形成的队列
六、死锁处理
更新中…明天再写…(✿◠‿◠)