【操作系统】调度算法(FCFS、SJF、HRRN、RR、优先级调度、多级反馈队列)

1. 批处理、分时、实时系统

1. 批处理系统

1.1 单道批处理系统

  • 内存中仅有一道作业,它无法充分利用系统中的全部资源,致使系统性能较差。

1.2 多道批处理系统

  • 用户所提交的作业都先存放在外存上并排成一个队列,称为“后备队列”,然后由作业调度程序按一定的算法从后备队列中选择若干个作业调入内存,使它们共享CPU和系统中的各种资源。

【优缺点】
(1)资源利用率高;(2)系统吞吐量大;(3)平均周转时间长;(4)无交互能力。

2. 分时系统
  • 分时系统是指,在一台主机上连接了多个带有显示器和键盘的终端,同一时间同意多个用户通过自己的终端,以交互方式使用计算机,共享主机中的资源。

【特征】
(1)多路性;(2)独立性;(3)及时性;(4)交互性。

3. 实时系统
  • 实时系统是指系统能及时响应外部事件的请求,在规定的时间内完毕对该事件的处理,并控制全部实时任务协调一致的执行。

2. 处理机调度级别

  • 一般来说,处理机调度可分为三个级别,分别是高级调度、中级调度和低级调度。
2.1 高级调度(作业调度)
  • 高级调度又称作业调度,作业就是用户程序及其所需的数据和命令的集合,作业管理就是对作业的执行情况进行系统管理的程序的集合;
  • 作业调度程序的主要功能是审查系统是否能满足用户作业的资源要求以及按照一定的算法来选取作业。
2.2 中级调度
  • 中级调度的主要目的是为了提高内存的利用率和系统吞吐量,使得暂时不运行的进程从内存对换到外存上。
2.3 低级调度(进程调度)
  • 低级调度又称进程调度,其主要功能是根据一定的算法将cpu分派给就绪队列中的一个进程;
  • 进程调度是操作系统中最基本的一种调度,其调度策略的优劣直接影响整个系统的性能。

3. 调度算法

3.1 先来先服务调度算法(FCFS)
  • 先来先服务(FCFS)调度算法是一种最简单的调度算法,该算法既可用于作业调度,也可用于进程调度;

  • 作业调度中采用该算法时,每次调度都是从后备作业队列中选择一个或多个最先进入该队列的作业,将它们调入内存,为它们分配资源、创建进程,然后放入就绪队列;

  • 进程调度中采用FCFS算法时,则每次调度是从就绪队列中选择一个最先进入该队列的进程,为之分配处理机,使之投入运行,该进程一直运行到完成或发生某事件而阻塞后才放弃处理机。

【例题】

进程到达时间服务时间
A03
B26
C44
D65
E82

简单模拟时间轴表示其过程:

012345678910111213141516171819
AAAA
BBBBBBB
CCCCC
DDDDDD
EEE

在这里插入图片描述

开始时间是上一个进程的结束时间
结束时间 = 开始时间 + 服务时间
周转时间 = 结束时间 - 到达时间
带权周转时间 = 周转时间 / 服务时间
进程到达时间服务时间开始时间结束时间周转时间带权周转时间
A030331
B263971.17
C4491392.25
D651318122.4
E821820126
  • FCFS调度算法,从表面上看,它对所有作业都是公平的,但若一个长作业先到达系统,就会使后面许多短作业等待很长时间,因此它不能作为分时系统和实时系统的主要调度策略。
3.2 短作业(进程)优先调度算法(SJ(P)F)
  • 短作业(进程)优先调度算法,是指对短作业或短进程优先调度的算法,它们可以分别用于作业调度和进程调度,是根据服务的时间经行选择;

  • 短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业,将它们调入内存运行;

  • 短进程优先(SPF)调度算法则是从就绪队列中选出一个估计运行时间最短的进程,将处理机分配给它,使它立即执行并一直执行到完成,或发生某事件而被阻塞放弃处理机时再重新调度。

【上述例题】

进程到达时间服务时间
A03
B26
C44
D65
E82
要注意作业/进程是否达到,达到越早、服务时间越短越先调入,针对该例题为:A-B-E-C-D

简单模拟时间轴表示其过程:

012345678910111213141516171819
AAAA
BBBBBBB
CCCCC
DDDDDD
EEE

在这里插入图片描述

进程到达时间服务时间开始时间结束时间周转时间带权周转时间
A030331
B263971.17
C441115112.75
D651520142.8
E8291131.5
  • SJF调度算法,对长作业不利;
  • 更严重的是,如果有一长作业进入系统的后备队列,由于调度程序总是优先调度那些短作业,将导致长作业长期不被调度(“ 饥饿”现象 )。
3.3 优先级调度算法
  • 优先级调度算法又称优先权调度算法,该算法既可以用于作业调度,也可以用于进程调度,该算法中的优先级用于描述作业运行的紧迫程度。

  • 在作业调度中,优先级调度算法每次从后备作业队列中选择优先级最髙的一个或几个作业,将它们调入内存,分配必要的资源,创建进程并放入就绪队列;

  • 在进程调度中,优先级调度算法每次从就绪队列中选择优先级最高的进程,将处理机分配给它,使之投入运行。

【根据新的更高优先级进程能否抢占正在执行的进程,可将该调度算法分为】

  • 非剥夺式优先级调度算法,当某一个进程正在处理机上运行时,即使有某个更为重要或紧迫的进程进入就绪队列,仍然让正在运行的进程继续运行,直到由于其自身的原因而主动让出处理机时(任务完成或等待事件),才把处理机分配给更为重要或紧迫的进程。

  • 剥夺式优先级调度算法,当一个进程正在处理机上运行时,若有某个更为重要或紧迫的进程进入就绪队列,则立即暂停正在运行的进程,将处理机分配给更重要或紧迫的进程。

【根据进程创建后其优先级是否可以改变,可以将进程优先级分为以下两种】

  • 静态优先级,优先级是在创建进程时确定的,且在进程的整个运行期间保持不变。确定静态优先级的主要依据有进程类型、进程对资源的要求、用户要求。

  • 动态优先级,在进程运行过程中,根据进程情况的变化动态调整优先级。动态调整优先级的主要依据为进程占有CPU时间的长短、就绪进程等待CPU时间的长短。

3.4 高响应比优先调度算法(HRRN)
  • 高响应比优先调度算法主要用于作业调度,该算法是对FCFS调度算法和SJF调度算法的一种综合平衡,同时考虑每个作业的等待时间和估计的运行时间。在每次进行作业调度时,先计算后备作业队列中每个作业的响应比,从中选出响应比最高的作业投入运行。

【响应比的变化规律可描述为:】

  • 响应比Rp = (等待时间+要求服务时间)/ 要求服务时间 = 1 +(等待时间 / 要求服务时间)

根据公式可知:

  • 当作业的等待时间相同时,则要求服务时间越短,其响应比越高,有利于短作业;

  • 当要求服务时间相同时,作业的响应比由其等待时间决定,等待时间越长,其响应比越高,因而它实现的是先来先服务;

  • 对于长作业,作业的响应比可以随等待时间的增加而提高,当其等待时间足够长时,其响应比便可升到很高,从而也可获得处理机,克服了饥饿状态,兼顾了长作业。

【例题】

作业到达时间服务时间
A06
B32
C44
D41

(1)先执行A作业,其余再通过响应比判断执行哪个;

作业到达时间服务时间开始时间结束时间周转时间带权周转时间
A060661
B32
C44
D41

(2)根据响应比,执行D作业;

等待时间 = 上一个作业调入完成时间 - 该作业到达的时间

响应比高的先执行

R(B) = 1 + (6 - 3)/ 2 = 2.5
R(C) = 1 + (6 - 4)/ 4 = 1.5
R(D)= 1 + (6 - 4) / 1 = 3

作业到达时间服务时间开始时间结束时间周转时间带权周转时间
A060661
B32
C44
D416733

(3)根据响应比,执行B作业;
R(B) = 1 + (7 - 3)/ 2 = 2
R(C) = 1 + (7 - 4)/ 4 = 0.75

作业到达时间服务时间开始时间结束时间周转时间带权周转时间
A060661
B3271073.5
C44
D416733

(4)执行最后C作业。

作业到达时间服务时间开始时间结束时间周转时间带权周转时间
A060661
B3271073.5
C441014102.5
D416733
3.5 时间片轮转调度算法(RR)
  • 时间片轮转调度算法主要适用于分时系统;

  • 在这种算法中,系统将所有就绪进程按到达时间的先后次序排成一个队列,进程调度程序总是选择就绪队列中第一个进程执行,即先来先服务的原则,但仅能运行一个时间片,如100ms。在使用完一个时间片后,即使进程并未完成其运行,它也必须释放出(被剥夺)处理机给下一个就绪的进程,而被剥夺的进程返回到就绪队列的末尾重新排队,等候再次运行。

  • 在时间片轮转调度算法中,时间片的大小对系统性能的影响很大。如果时间片足够大,以至于所有进程都能在一个时间片内执行完毕,则时间片轮转调度算法就退化为先来先服务调度算法;如果时间片很小,那么处理机将在进程间过于频繁切换,使处理机的开销增大,而真正用于运行用户进程的时间将减少,因此时间片的大小应选择适当。

  • 时间片的长短通常由以下因素确定:系统的响应时间、就绪队列中的进程数目和系统的处理能力。

【例题】

转载例题出处:https://blog.csdn.net/u013630349/article/details/47732731
在这里插入图片描述
在这里插入图片描述

3.6 多级反馈队列调度算法
  • 多级反馈队列调度算法是时间片轮转调度算法和优先级调度算法的综合和发展;

  • 通过动态调整进程优先级和时间片大小,多级反馈队列调度算法可以兼顾多方面的系统目标。

  • 例如,为提高系统吞吐量和缩短平均周转时间而照顾短进程;为获得较好的I/O设备利用率和缩短响应时间而照顾I/O型进程;同时,也不必事先估计进程的执行时间。

【特点】

  • 提高吞吐量和缩短平均周转时间而照顾短进程;
  • 为获得较好的I/O设备利用率和缩短响应时间而照顾I/O型进程;
  • 不必事先估计进程的执行时间。

【如何工作】

  1. 多个就绪队列,第一队列优先级最高;
  2. 赋予各个队列中进程执行时间片的大小不一样,优先级越高的队列中,多个进程的运行时间片越小;
  3. 新进程进入内存后,按FCFS原则排队等待调度。

【学习多级反馈调度算法链接】

1. 多级反馈队列调度算法

2. 多级反馈队列调度算法

3. 多级反馈队列简图

  • 67
    点赞
  • 366
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
以下是常见的作业调度算法的C语言实现: 1. FCFS(先来先服务) ```c #include <stdio.h> int main() { int n, i; float avg_tat = 0, avg_wt = 0; int burst[20], tat[20], wt[20]; printf("Enter the number of processes: "); scanf("%d", &n); printf("Enter the burst time for each process:\n"); for(i=0; i<n; i++) { printf("P[%d]: ", i+1); scanf("%d", &burst[i]); } tat[0] = burst[0]; wt[0] = 0; for(i=1; i<n; i++) { tat[i] = tat[i-1] + burst[i]; wt[i] = tat[i-1]; } printf("\nProcess\tBurst Time\tTurnaround Time\tWaiting Time\n"); for(i=0; i<n; i++) { printf("P[%d]\t%d\t\t%d\t\t%d\n", i+1, burst[i], tat[i], wt[i]); avg_tat += tat[i]; avg_wt += wt[i]; } avg_tat /= n; avg_wt /= n; printf("\nAverage Turnaround Time: %.2f", avg_tat); printf("\nAverage Waiting Time: %.2f", avg_wt); return 0; } ``` 2. SJF作业优先) ```c #include <stdio.h> #include <stdlib.h> struct process { int id; int burst; int arrival; int tat; int wt; }; void swap(struct process *a, struct process *b) { struct process temp = *a; *a = *b; *b = temp; } void sort(struct process arr[], int n) { int i, j; for(i=0; i<n-1; i++) { for(j=0; j<n-i-1; j++) { if(arr[j].burst > arr[j+1].burst) { swap(&arr[j], &arr[j+1]); } } } } int main() { int n, i, j; float avg_tat = 0, avg_wt = 0; struct process p[20]; printf("Enter the number of processes: "); scanf("%d", &n); printf("Enter the arrival time and burst time for each process:\n"); for(i=0; i<n; i++) { printf("P[%d]: ", i+1); p[i].id = i+1; scanf("%d %d", &p[i].arrival, &p[i].burst); } sort(p, n); p[0].tat = p[0].burst; p[0].wt = 0; for(i=1; i<n; i++) { int sum = 0; for(j=0; j<i; j++) { sum += p[j].burst; } p[i].tat = sum + p[i].burst - p[i].arrival; p[i].wt = p[i-1].wt + p[i-1].burst - p[i].arrival; if(p[i].wt < 0) { p[i].wt = 0; } } printf("\nProcess\tArrival Time\tBurst Time\tTurnaround Time\tWaiting Time\n"); for(i=0; i<n; i++) { printf("P[%d]\t%d\t\t%d\t\t%d\t\t%d\n", p[i].id, p[i].arrival, p[i].burst, p[i].tat, p[i].wt); avg_tat += p[i].tat; avg_wt += p[i].wt; } avg_tat /= n; avg_wt /= n; printf("\nAverage Turnaround Time: %.2f", avg_tat); printf("\nAverage Waiting Time: %.2f", avg_wt); return 0; } ``` 3. PSA(优先级调度算法) ```c #include <stdio.h> #include <stdlib.h> struct process { int id; int burst; int priority; int tat; int wt; }; void swap(struct process *a, struct process *b) { struct process temp = *a; *a = *b; *b = temp; } void sort(struct process arr[], int n) { int i, j; for(i=0; i<n-1; i++) { for(j=0; j<n-i-1; j++) { if(arr[j].priority > arr[j+1].priority) { swap(&arr[j], &arr[j+1]); } } } } int main() { int n, i, j; float avg_tat = 0, avg_wt = 0; struct process p[20]; printf("Enter the number of processes: "); scanf("%d", &n); printf("Enter the burst time and priority for each process:\n"); for(i=0; i<n; i++) { printf("P[%d]: ", i+1); p[i].id = i+1; scanf("%d %d", &p[i].burst, &p[i].priority); } sort(p, n); p[0].wt = 0; p[0].tat = p[0].burst; for(i=1; i<n; i++) { p[i].wt = p[i-1].wt + p[i-1].burst; p[i].tat = p[i].wt + p[i].burst; } printf("\nProcess\tBurst Time\tPriority\tTurnaround Time\tWaiting Time\n"); for(i=0; i<n; i++) { printf("P[%d]\t%d\t\t%d\t\t%d\t\t%d\n", p[i].id, p[i].burst, p[i].priority, p[i].tat, p[i].wt); avg_tat += p[i].tat; avg_wt += p[i].wt; } avg_tat /= n; avg_wt /= n; printf("\nAverage Turnaround Time: %.2f", avg_tat); printf("\nAverage Waiting Time: %.2f", avg_wt); return 0; } ``` 4. RR(时间片轮转调度算法) ```c #include <stdio.h> #include <stdlib.h> struct process { int id; int burst; int remaining; int tat; int wt; }; int main() { int n, i, t = 0, count = 0, tq; float avg_tat = 0, avg_wt = 0; struct process p[20]; printf("Enter the number of processes: "); scanf("%d", &n); printf("Enter the time quantum: "); scanf("%d", &tq); printf("Enter the burst time for each process:\n"); for(i=0; i<n; i++) { printf("P[%d]: ", i+1); p[i].id = i+1; scanf("%d", &p[i].burst); p[i].remaining = p[i].burst; } while(count < n) { for(i=0; i<n; i++) { if(p[i].remaining > 0) { if(p[i].remaining > tq) { t += tq; p[i].remaining -= tq; } else { t += p[i].remaining; p[i].wt = t - p[i].burst; p[i].remaining = 0; count++; p[i].tat = t; avg_tat += p[i].tat; avg_wt += p[i].wt; } } } } avg_tat /= n; avg_wt /= n; printf("\nProcess\tBurst Time\tTurnaround Time\tWaiting Time\n"); for(i=0; i<n; i++) { printf("P[%d]\t%d\t\t%d\t\t%d\n", p[i].id, p[i].burst, p[i].tat, p[i].wt); } printf("\nAverage Turnaround Time: %.2f", avg_tat); printf("\nAverage Waiting Time: %.2f", avg_wt); return 0; } ``` 5. MFS(多级反馈队列调度算法) ```c #include <stdio.h> #include <stdlib.h> struct process { int id; int burst; int remaining; int priority; int tat; int wt; }; void swap(struct process *a, struct process *b) { struct process temp = *a; *a = *b; *b = temp; } void sort(struct process arr[], int n) { int i, j; for(i=0; i<n-1; i++) { for(j=0; j<n-i-1; j++) { if(arr[j].priority < arr[j+1].priority) { swap(&arr[j], &arr[j+1]); } } } } int main() { int n, i, j, t = 0, count = 0; float avg_tat = 0, avg_wt = 0; struct process p[20]; printf("Enter the number of processes: "); scanf("%d", &n); printf("Enter the burst time and priority for each process:\n"); for(i=0; i<n; i++) { printf("P[%d]: ", i+1); p[i].id = i+1; scanf("%d %d", &p[i].burst, &p[i].priority); p[i].remaining = p[i].burst; } sort(p, n); while(count < n) { for(i=0; i<n; i++) { if(p[i].remaining > 0) { if(p[i].remaining > 2) { t += 2; p[i].remaining -= 2; p[i].priority--; } else { t += p[i].remaining; p[i].wt = t - p[i].burst; p[i].remaining = 0; count++; p[i].tat = t; avg_tat += p[i].tat; avg_wt += p[i].wt; } } } sort(p, n); } avg_tat /= n; avg_wt /= n; printf("\nProcess\tBurst Time\tPriority\tTurnaround Time\tWaiting Time\n"); for(i=0; i<n; i++) { printf("P[%d]\t%d\t\t%d\t\t%d\t\t%d\n", p[i].id, p[i].burst, p[i].priority, p[i].tat, p[i].wt); } printf("\nAverage Turnaround Time: %.2f", avg_tat); printf("\nAverage Waiting Time: %.2f", avg_wt); return 0; } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值