处理机的调度层次
作业调度(高级调度) 对换(中级调度) 进程调度(低级调度)
处理机调度时机
当前运行的进程主动放弃处理机
- 进程正常终止
- 运行过程种发生异常而终止
- 进程主动请求阻塞(如等待I/O)
当前运行的进程被动放弃处理机
- 分给进程的时间片用完
- 有更紧急的事需要处理(如IO中断)
- 有更高优先级的进程进入就绪队列
在并发执行的环境下,引起进程调度的事件有: 1.完成任务 正在执行的进程运行完成,主动释放对CPU的控制。 2.等待资源 由于等待某些资源或事件发生,正在运行的进程不得不放弃CPU,进入阻塞状态。 3.运行时间到 在分时系统中,当前进程使用完规定的时间片,时钟中断,使该进程让出CPU。 4.进入睡眠状态 执行中的进程自己调用阻塞原语将自己阻塞起来,进入睡眠等待状态。 5.发现标志 执行完系统调用,从系统程序返回用户进程时,可认为系统进程执行完毕,从而可调度新的用户进程执行。 当CPU执行方式是可剥夺时,引起进程调度的事件还应再加一条:优先级变化。 6.优先级变化 就绪队列中某进程的优先级高于当前执行进程的优先级时,将引起进程调度。
不能进行进程调度与切换的情况:
- 处理中断的过程中
- 进程在操作系统内核程序临界区中
- 在原子操作过程中(原语)
处理及调度性能评价指标
CPU利用率越高,周转时间、响应时间越小
优先级调度算法的类型
(1) 非抢占式优先级调度算法: 只有因发送其他事件,使该进程进入阻塞状态,该进程才放弃处理机,系统在就绪态进程中,找另一个有极限级最高的进程,将处理机分配给它。 适用范围: 批处理系统、某些对实时性要求不严的实时系统中 (2) 抢占式优先级调度算法: 在其执行期间,如果又出现了另一个优先级更高的进程,进程调度程序就立即停止当前进程的执行,重新将处理机分配给信道的优先级更高的进程 适用范围: 比较严格的实时系统、对性能要求较高的批处理和分时系统中
死锁
概念: 如果两个或两个以上进程中,每一个进程都在等待获得由其他进程把持的某种系统资源,导致这批进程间相互永久等待的情况,称为死锁
原因: 各进程竞争有限的资源,进程推进顺序不当
死锁产生的必要条件:
- 互斥条件:对于一个排他性资源,某一时刻最多只能由一个进程占有
- 占有且申请条件: 进程至少已经占有一个资源,但又申请新的资源
- 不可抢占条件: 进程所获得的资源在未使用完之前不不能被其他进程夺取该资源
- 环路条件: 如果死锁产生,则一定存在一个循环等待的环路
死锁的预防(静态策略):
- 摒弃占有且申请条件
摒弃占有且申请条件可以采用二种方法:
(1)资源的静态预分配。 (2)释放已占资源策略。 - 不可抢占条件 采取抢占策略
- 环路条件 实行资源的有序分配策略
死锁的避免(动态策略):
- 系统的安全状态
指系统中的所有进程能够按照某种次序得到资源,并且依次地运行完毕,这种进程序列就是安全序列
银行家算法
- 系统可利用资源向量Available:Available[j]=k,则表示系统中现有Rj类资源K个
- 最大需求矩阵Max:Max[i,j]=k,表示第i个进程需要Rj类资源地最大数目为K
- 分配矩阵Allocation: Allocation[i,j]=k,则表示第i个进程当前已分得Rj类资源地数目为K
- 申请矩阵Need: Need[i,j]=k,表示第i个进程还需要Rj类资源k个
Need[i,j]=Max[i,j]-Allocation[i,j]
当进程Pi发出资源请求后,系统按下述步骤进行检查:
(1)如果Requesti≤Need[i],便转向步骤2;否则显示出错,因为它所需要的资源数已超过它所事先要求的最大值。
(2)如果Requesti≤Available,便转向步骤(3);否则,表示尚无足够资源,Pi须等待。
(3)假设系统将资源分配给Pi,则需修改如下数据结构的值:
Available:= Available –Request[i]; Allocation[i]:=Allocation[i]+Requesti; Need[i]:=Need[i]-Request[i];
(4)系统执行安全性算法,检查若此次资源分配后,系统是否处于安全状态。如果是安全的,则将资源真正地分配给进程Pi,否则,将本进程的试探分配作废,恢复原来的资源分配状态,进程Pi等待。
某系统有同类资源m个,n个并发进程可共享该类临界资源。 每个进程最后可申请多少个该类临界资源,保证系统一定不会发送死锁。 设每个进程最多申请该类资源地最大量为X 公式:X<=1+[(m-1)/n]
java经典死锁案例:
public static void main(String[] args) {
// deadLock
Object a = new Object();
Object b = new Object();
new Thread(() -> {
synchronized (a) {
System.out.println("get a");
try {
Thread.sleep(Long.parseLong("1000"));
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b) {
System.out.println("want get b");
}
}
}, "a").start();
new Thread(() -> {
synchronized (b) {
System.out.println("get b");
try {
Thread.sleep(Long.parseLong("1000"));
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a) {
System.out.println("want get a");
}
}
}, "b").start()
分析:线程1先获得a锁后休息1秒钟后想获得B锁,而线程2先获得b锁后休息1秒钟后想获得A锁,两个线程同时运行,线程1获得A锁的同时线程2获得B锁,此时线程1想要线程2的B锁,线程2想要线程1的A锁,最后两者的锁都无法得到释放,造成死锁现象