程序:是静态的,就是个存放在磁盘里的可执行文件,如: Tim.exe
进程:是动态的,是程序的一次执行过程,如:可同时启动多次Tim程序
同一个程序多次执行会对应多个进程
同时挂三个QQ号,会对应三个QQ进程,它们的PCB、数据段各不相同,但程序段的内容都是相同的(都是运行着相同的QQ程序)
五态模型:
创建态: 进程正在被创建时,它的即态是“创建态”,在这个阶段操作系统会为进程分配资源、初始化PCB。
就绪态: 当进程创建即成后,便进入“就绪态”,处于就绪态的进程已经具备运行条件,但由于没有空闲CPU,就暂时不能运行。
运行态: 当CPU空闲时,操作系统就会选择一个就绪进程,让它上处理机运行。此时该进程就由就绪态变为运行态,CPU会执行该进程的指令序列。
阻塞态: 在进程运行的过程中,当能会请求等待某个事件的发生(如等待某种系统资源的分配,或者等待其他进程的响应)。在这个事件发生之前,进程无法继续往下执行,此时操作系统会让这个进程下CPU,并让它进入“阻塞态”
当CPU空闲时,又会选择另一个“就绪态”进程上CPU运行
终止态: 一个进程当以执行exit
系统调用,请求操作系统终止该进程。此时该进程会进入“终止态”,操作系统会让该进程下CPU,并回收内存空间等资源,最后还要回收该进程的PCB。当终止进程的工作完成之后,这个进程就彻底消失了。
注意:进程PCB中存放着标识当前进程状态的变量state
,如1表示创建态、2表示就绪态、3表示执行态……
链接方式:
注:还有索引表的组织方式
状态转换的过程要用原语实现,也就是说进程状态之间的转换要 “一气呵成”
举个最简单的例子:
假设当前进程为阻塞态,现等待的事件已发生,要变为就绪态。那么最少需要经历两个步骤:
(1) 修改该进程PCB中state的值为就绪
(2) 将该进程放到就绪队列中
如果不一气呵成,在执行完步骤一后被中断,那么该进程依旧在阻塞队列中,但state值为就绪,就可能会导致系统错误
可以用开/关中断指令(特权指令)来实现原语的”原子性“
正常情况下CPU每执行完一条指令都会例行检查是否有中断信号需要处理,如果有,则暂停运行当前这个进程,转而执行相应的中断处理程序。
当CPU执行了关中断指令之后,就不再例行检查中断信号,直到执行开中断指令之后才会恢复检查。这样,关中断、开中断之间的这些指令序列就是不会被中断的,这就实现了“原子性”
总结:
进程状态之间的转换无外乎要做三类事情:
扩展:
Q:CPU在空闲时(就绪队列为空时)做什么?
A:其实CPU空闲时并不是什么都不干,而是在运行空闲任务(idle tasks)。
空闲任务可能听起来有点自相矛盾,关键是你要理解CPU既然通电,那么就必须时刻不停地在运转,即使他什么正事也不干。
在哲学上对应的词汇就是所谓的“忙等待”(busy waiting),本质是让CPU不停地去计算某个条件,看看是否为true。
调度 —— 处理机调度(低级调度)
注:主动放弃与被动放弃是指当前运行的进程以何种情况放弃处理机。
注:
临界资源: 一个时间段内只允许一个进程使用的资源。各进程需要互斥地访问临界资源。
临界区: 访问临界资源的那段代码。
内核程序临界区: 一般是用来访问某种内核数据结构的,比如进程的就绪队列(由各就绪进程的PCB组成)
注意: 进程检换是有代价的,因此如果过于频繁的进行进程调度、检换,必然会使整个系统的效率降低,使系统大部分时间都花在了进程检换上,而真正用于执行进程的时间减少。
又称非抢占方式。即,只允许进程主动放弃处理机。在运行过程中即便有更紧迫的任务到达,当前进程依然会继续使用处理机,直到该进程终止或主动要求进入阻塞态。
实现简单,系统开销小但是不能及时处理紧急任务,适合于早期的批处理系统
又称抢占方式。当一个进程正在处理机上执行时,如果有一个更重要或更紧迫的进程需要使用处理机,则立即暂停正在执行的进程,将处理机分配给更重要紧迫的那个进程。
可以优先处理更紧急的进程,也可实现让各进程按时间片轮流执行的功能(通过时钟中断)。适合于分时操作系统、实时操作系统
实现方式:把处理机分配给最先进入就绪队列的进程
优点:实现简单
缺点:表面上公平,服务质量不佳 、对短进程不利;所以该算法很少作为进程调度主算法,常常作为一种辅助调度算法
实现方式:从就绪队列中选择估计运⾏时间最短的进程,为该进程分配CPU
优点:可获得较好的调度性能
缺点:程的CPU执行期难以准确得到、对长进程不利
实现方式:响应比 =(等待时间 + 要求的服务时间)/ 要求的服务时间 ,每次选取响应比最高的进程调度
优点:对短进程有利,并且考虑了等待时间
缺点:计算响应比有一定的系统开销
实现方式:将CPU分配给就绪队列中优先级最高的进程
优点:实现简单、可以处理紧急事件
缺点:优先级筛选有一定的系统开销
实现方式:通常用在分时系统,它轮流地调度系统中所有就绪进程,使就绪进程依次获得一个时间片的运行时间(记为 t t t)。系统为就绪队列中的每一个进程分配一个时间片,在使用完一个时间片后即使进程还没有运行完毕,也要强迫其释放处理机,让给另一个进程使用。它自己则返回到就绪队列末尾,排队等待下一次调度的到来。 t t t的大小不仅影响CPU的利用率,也影响平均周转时间
t t t 过大:无异于先来先服务
t t t 过小:调度程序频率上升,系统耗费在调度上的时间增加,真正运行用户程序的时间减少
时间片长短确定遵循原则——既要保证系统各个用户进程及时地得到响应,又不要由于时间片太短而增加调度的开销,降低系统的效率
UNIX操作系统采取的便是这种调度算法
实现方式:多级(假设N级)反馈队列轮转算法
Ⅰ. 设有N个队列 ( Q 1 , Q 2.... Q N ) (Q1,Q2....QN) (Q1,Q2....QN),其中处理机对各个队列处理的优先级是不一样的。一般来说,优先级 P r i o r i t y ( Q 1 ) > P r i o r i t y ( Q 2 ) > . . . > P r i o r i t y ( Q N ) Priority(Q1) > Priority(Q2) > ... > Priority(QN) Priority(Q1)>Priority(Q2)>...>Priority(QN)。也就是说,位于 Q 1 Q1 Q1中的任何一个进程都要比 Q 2 Q2 Q2中的任何一个进程被处理的优先级要高,依次类推其它的队列。
Ⅱ . 对于优先级最低的队列来说,里面是遵循时间片轮转法。也就是说,位于队列 Q N QN QN中有 M M M个进程,它们的运行时间是通过 Q N QN QN这个队列所设定的时间片来确定的;对于其他队列,遵循的是先来先服务算法,每一进程分配一定的时间片,若时间片运行完时进程未结束,则进入下一优先级队列的末尾。
Ⅲ . 各个队列的时间片是一样的吗?不一样,这就是该算法设计的精妙之处。各个队列的时间片是随着优先级的增加而减少的,也就是说,优先级越高的队列中它的时间片就越短。同时,为了便于那些超大作业的完成,最后一个队列 Q N QN QN(优先级最低的队列)的时间片一般很大。
算法描述:
1、进程在进入就绪队列等待时,首先进入优先级最高的Q1等待。
2、首先调度优先级高的队列中的进程。若高优先级中队列中已没有调度的进程,则调度次优先级队列中的进程。
3、对于同一个队列中的各个进程,按照FCFS分配时间片调度。比如Q1队列的时间片为N,那么Q1中的作业在经历了N个时间片后若还没有完成,则进入Q2队列等待,若Q2的时间片用完后作业还不能完成,一直进入下一级队列末尾,直至完成。
4、在最后一个队列QN中的各个进程,按照时间片轮转分配时间片调度。
5、在低优先级的队列中的进程在运行时,又有新到达的作业,此时须立即把正在运行的进程放回当前队列的队尾,然后把处理机分给高优先级进程(抢占式)。特别说明,当再度运行到当前队列的该进程时,仅分配上次还未完成的时间片,不再分配该队列对应的完整时间片。
优点:多级反馈队列调度算法既能使高优先级的进程得到响应又能使短进程迅速完成。
CPU利用率 = C P U 忙碌的时间 总时间 \frac{CPU忙碌的时间}{总时间} 总时间CPU忙碌的时间
系统吞吐量(单位时间内完成作业的数量) = 总共完成多少道作业 完成这些作业所用的时间 \frac{总共完成多少道作业}{完成这些作业所用的时间} 完成这些作业所用的时间总共完成多少道作业
作业周转时间 = 作业完成时间 − 作业提交时间 作业完成时间 - 作业提交时间 作业完成时间−作业提交时间
作业平均周转时间 = 各作业周转时间之和 作业数 \frac{各作业周转时间之和}{作业数} 作业数各作业周转时间之和
带权周转时间 = 作业周转时间 作业实际运行时间 \frac{作业周转时间}{作业实际运行时间} 作业实际运行时间作业周转时间
平均带权周转时间 = 各作业周转时间之和 作业数 \frac{各作业周转时间之和}{作业数} 作业数各作业周转时间之和