A 进程调度1—静态非剥夺式优先级调度计算平均作业周转时间
要求输入3个进程的信息,假设这些进程均是在0时刻同时到达,若进程调度采用非剥夺式静态优先级(优先数数值大的表示优先级比较高;如果遇到优先级一样,按照输入顺序执行。),计算并输出平均作业周转时间。
import java.util.ArrayList; import java.util.Scanner; /** * @Author Tiam * @Date 2022/10/13 20:59 * @Description: 静态非剥夺式优先级调度计算平均作业周转时间 */ public class Main { // 进程数 public static final int PROCESS_NUM = 3; public static void main(String[] args) { ArrayList<Process> processes = new ArrayList<>(); for (int i = 0; i < PROCESS_NUM; i++) { processes.add(input(new Process())); } // 排序: 以优先数 降序排列, 相同则按输入顺序排列 processes.sort((o1, o2) -> { if (o1.priority == o2.priority) { return o1.name.compareTo(o2.name); } else { return o2.priority - o1.priority; } }); // 当前时间 , 总周转时间 int currentTime = 0, allTime = 0; for (Process process : processes) { currentTime += process.runTime; process.turnaroundGTime = currentTime; allTime += process.turnaroundGTime; } // 保留小数点后一位 System.out.printf("%.1f", (float) allTime / processes.size()); } static Scanner scanner = new Scanner(System.in); static Process input(Process p) { p.name = scanner.next(); p.priority = scanner.nextInt(); p.runTime = scanner.nextInt(); return p; } } class Process { /** * 进程名 */ String name; /** * 优先数 数值大的表示优先级比较高;如果遇到优先级一样,按照输入顺序执行 */ int priority; /** * 运行时间 */ int runTime; /** * 周转时间 */ int turnaroundGTime; }
B 进程调度2–最高响应比优先计算每个作业的周转时间
要求输入3个进程的信息,按照最高响应比优先的调度算法计算并输出每个进程的周转时间。(若两个进程的响应比相同,则优先选择先进入的进程。若两个进程的响应比相同,而且进入时刻也相同,则按照输入的顺序执行,如:P4和P6的响应比相同且进入时刻也相同,如P4先输入则选择P4先执行)
import java.util.*; /** * @Author Tiam * @Date 2022/10/15 14:39 * @Description: 最高响应比 优先计算每个作业的周转时间 * 响应比 =1+(等待时间/处理时间) 随着等待时间增加, 响应比增大 * 响应比相同且进入时刻也相同, 选择 先输入的 */ public class Main { // 进程数 public static final int PROCESS_NUM = 3; public static void main(String[] args) { // 待执行的进程集合 List<Process> processes = new ArrayList<>(); for (int i = 0; i < PROCESS_NUM; i++) { processes.add(input(new Process())); } // 复制一份用于输出 List<Process> processes1 = new ArrayList<>(processes); // 模拟以 最高响应比优先算法 运行进程 int currentTime = minTime(processes); while (!processes.isEmpty()) { // 个数大于一 , 重新计算每个进程的响应比 if (processes.size() > 1) { for (Process p : processes) { p.responseRatio = 1 + (currentTime - p.inTime) / (float) p.runTime; } // 按响应比 降序排列 Collections.sort(processes, (o1, o2) -> { // 如果响应比相同, 按进入顺序排序 if (o2.responseRatio == o1.responseRatio) { // 如果进入时间相同, 按输入顺序运行 if (o1.inTime == o2.inTime) { return o1.name.compareTo(o2.name); } else { return o1.inTime - o2.inTime; } } else { return o2.responseRatio > o1.responseRatio ? 1 : -1; } }); } // 当前需执行的 进程 Process currentP = processes.get(0); // 当前时间 不小于 当前进程的运行时间 while (currentTime < currentP.inTime) currentTime++; //当前时间 大于等于 进程的进入时间, 可开始执行程序 currentTime += currentP.runTime; currentP.turnaroundGTime = currentTime - currentP.inTime; // 从集合中移除 processes.remove(currentP); } processes1.forEach(p -> System.out.print(p.turnaroundGTime + " ")); } /** * 返回所有程序中 最小的进入时间 * * @param processes * @return */ static int minTime(List<Process> processes) { int min = processes.get(0).inTime; for (Process p : processes) if (p.inTime < min) min = p.inTime; return min; } static Scanner scanner = new Scanner(System.in); static Process input(Process p) { p.name = scanner.next(); p.inTime = scanner.nextInt(); p.runTime = scanner.nextInt(); return p; } } class Process { /** * 进程名 */ String name; /** * 进程的进入时刻 */ int inTime; /** * 所需运行时间 */ int runTime; /** * 周转时间 */ int turnaroundGTime; /** * 响应比 = 1+(等待时间/处理时间) */ float responseRatio = 1; }
E 存储管理—FIFO页面替换算法计算中断次数
在请求分页式存储管理方式中,要求输入一个对5个页面的访问序列,输出当系统分配给进程物理页框数为m个时,按照FIFO页面替换算法的缺页中断次数(假设初始时页框均为空)。
# include <stdio.h> # include <stdlib.h> # include <string.h> int main(){ int n,m,i,j,temp,pd,k; int *a;//动态数组a用来存放页面访问序列 int *b;//动态数组b用来表示内存结构 int sum=0;//存储缺页中断次数 scanf("%d",&n); a=(int *)malloc(n*sizeof(int)); for(i=0;i<n;i++){ scanf("%d",&a[i]); } scanf("%d",&m); b=(int *)malloc(m*sizeof(int)); //初始化内存结构 for(i=0;i<m;i++){ b[i]=-1; } for(i=0;i<n;i++){ pd=0; //此变量用于判断新加入的数据是否和内存结构是否相同 for(j=0;j<m;j++){ //此层循环用于比较内存结构中的数据和新加入的页面访问序列是否相同 if(a[i]==b[j]){ //新加入的数据是a[i] pd=1; } } if(pd==0){ //无相同时:更新内存结构,缺页次数加一 for(k=m;k>0;k--){ //更新内存结构 b[k]=b[k-1]; } b[0]=a[i]; //b[0]单独处理 sum++; } } printf("%d",sum); system("pause"); return 0; }
D 存储管理—可变分区存储管理方式的最佳适应分配算法
当内存管理采用可变分区分配方案时,要求输入多个空闲分区和进程内存请求序列,输出显示采用最佳适应分配算法分配给各个进程的分区编号。
///*思路*/// //首先 将内存空间排序或者直接找到一个合适的(最小的内存空间与进程适配)最佳适应分配 //再从被找到的这个内存空间开始按照顺序往下寻找 合适的内存空间适配下一进程 下次适应分配法 # include <stdio.h> # include <stdlib.h> # include <string.h> void sort(int a[],int n) { int i,j,temp,min; for(i=0;i<n-1;i++) { min=i; for(j=i+1;j<n;j++) while(a[j]<a[min]) min=j; if(min!=i) { temp=a[min]; a[min]=a[i]; a[i]=temp; } } } int main(){ int n,i,j,k,p=0,min=10000; int *a; int b[3]; int *c;//该数组用来存放a数组中原来的位置 int num=0,panduan=0; scanf("%d",&n); a=(int *)malloc(n*sizeof(int)); c=(int *)malloc(n*sizeof(int)); memset(a, 0, n); for(i=0;i<n;i++){ scanf("%d",&a[i]); c[i]=a[i]; } for(i=0;i<3;i++){ scanf("%d",&b[i]); } ///*数据处理*/// sort(a,n);//对a数组排序 //p是存储当前查找的下标 p是用来下次适应分配法的下标的位置 i不应该是下标 i是控制循环的次数为n次 while(num<3){ panduan=0; for(i=0;i<n && b[num]!=0;i++){ if(p+i>=n){ //处理下标问题 首尾相连 p=p+i-n; } //printf("p--->%d\n",p); //printf("b[0]--->%d a[p+i]--->%d\n",b[num],a[p+i]); if(b[num]<=a[p+i] && b[num]!=0){ panduan=1;//找到合适的存储空间 p=p+i;//此处是该程序可能会出错的关键****** for(j=0;j<n && b[num]!=0;j++){ //匹配原数组内容 if(c[j]==a[p]){ printf("%d ",j+1); c[j]=c[j]-b[num]; a[p]=a[p]-b[num];//空间占用 b[num]=0;//移入内存 } } } } if(panduan==0){ printf("false "); } num++; } free(a); free(c); system("pause"); return 0; }
L 带存储管理的处理器调度4
现有一个内存为100K的采用位示图进行页面管理的道数为2道的多道程序设计系统,若作业调度采用高优先级(优先数越大优先级越大)调度算法(如果遇到优先级一样且只能调入一道作业时,按照输入顺序选择调度对象。),进程调度采用非剥夺式的SJF调度算法(如果遇到运行时间相同的进程,按照输入顺序选择调度对象。)。要求输入3个进程信息,输出当三个作业同时提交进入调度时进程的运行顺序。
# include <stdio.h> # include <stdlib.h> struct Pro{ char name[10];//进程名 int space;//所需内存空间 int time;//运行时间 int pri;//优先级 int grade_pri;//优先级排名 3 2 1 优先级越大排名越大 int ready; }pros [3]; void sort_pri(struct Pro *pros){ if(pros[0].pri<pros[1].pri){ //判断优先级 pros[1].grade_pri++; }else{ pros[0].grade_pri++; } if(pros[0].pri<pros[2].pri){ pros[2].grade_pri++; }else{ pros[0].grade_pri++; } if(pros[1].pri<pros[2].pri){ pros[2].grade_pri++; }else{ pros[1].grade_pri++; } } int main(){ struct Pro *pros_p=pros; int N=100;//可用内存 int i,j,k,min,min_xb=0; int sum_space=0;//当前占用的内存 ///*输入部分*/// for(i=0;i<3;i++){ scanf("%s %d %d %d",pros[i].name,&pros[i].space,&pros[i].time,&pros[i].pri); pros[i].grade_pri=1; pros[i].ready=0;//是否进入就绪态 未进入为0 进入为1 运行为3 } ///*数据处理*/// sort_pri(pros_p); for(j=0;j<3;j++){ //当三个作业都已经进入过就绪态 终止循环 2-sum_ready>0 ///*作业处理部分*/// for(i=3;i>0;i--){ //找出优先级最大的作业 for(k=0;k<3;k++){ if(pros[k].grade_pri==i && pros[k].ready==0 && (sum_space+pros[k].space) <= N){ sum_space=sum_space+pros[k].space; pros[k].ready=1; } } } ///*进程处理部分*/// min=101; for(i=0;i<3;i++){ //该循环用于找出运行时间最短的进程 if(min>pros[i].time && pros[i].ready==1){ min=pros[i].time; min_xb=i; } } sum_space=sum_space-pros[min_xb].space;//将已用内存释放 pros[min_xb].ready=3;//表示该进程已经运行 printf("%s ",pros[min_xb].name); } system("pause"); return 0; }
J 存储管理2
现有一个8*8的存储器,要对其空间进行分配。(下标从0开始,最后一个内存块下标为63)。现已有块号为2、7、13、23、37、47、59、61的几个内存块被占用。要求输入需分配的进程数M(0<M<=56),接下来输入为M个整型数,每个数为各个进程需占用的内存块数。当分配到某进程时,其剩余空闲块数可以分配,就输出当前进程分配的最后一个内存空间的下标。当分配到某进程时,其进程块数超出剩余空闲块数无法分配,输出为“false”(不含双引号,且为全小写)。输出的多个下标(或"false")之间用空格隔开。
#include <stdio.h> #include <string.h> int main() { void funsave(int n,int arr[64],int residue); int arr[64]={0}; int num[200]={0}; int inputnum; int i=0; int x[64]={0}; int sumsheng=56; char thirdName[10]; char str[10]; int getInTStr; arr[2]=1; arr[7]=1; arr[13]=1; arr[23]=1; arr[37]=1; arr[41]=1; arr[47]=1; arr[59]=1; arr[61]=1; scanf("%d",&inputnum); for (i = 0; i < inputnum; i++) { scanf("%d",&num[i]); if (sumsheng>num[i]) { sumsheng=sumsheng-num[i]; } x[i]=sumsheng; } for (i = 0; i < inputnum; i++) { funsave(num[i],arr,x[i]); } return 0; } void funsave(int n,int arr[64],int residue){ int i=0; int count=0; int indexI=0; int flag=0; int arr1[20]; int arr2[20]; int finallyIndex=0; int arrindex=0; int arrindex2=0; // printf("start n:%d\n",n); // printf("getInTStr:%d\n",getInTStr); if (n>residue) { printf("false "); }else{ if (arr[0]==0) { for (i = 0; i < n; i++) { if (arr[i]==1) { count++; } } for (i = 0; i < count+n; i++) { if (arr[i]==0) { arr2[arrindex2]=i; arrindex2++; } arr[i]=1; } printf("%d ", n+count-1); }else{ for (i = 0; i < 64; i++) { if (arr[i]==0) { indexI=i; goto LOOP; } } LOOP:for(i=indexI;i<indexI+n;i++){ if (arr[i]==1) { count++; } } for (i = indexI; i < indexI+count+n; i++) { if (arr[i]==0) { finallyIndex=i; arr1[arrindex]=i; arrindex=arrindex+1; } arr[i]=1; } printf("%d ", finallyIndex); } } }
F 驱动调度—采用电梯调度算法排列出磁盘请求响应次序
题目描述
要求输入一个柱面访问请求序列以及当前磁头所在柱面号和移动方向,输出采用电梯调度算法时移动臂响应的柱面访问序列。
#include <stdio.h> #include <stdlib.h> #define maxnum 100 void LOOK(int visitlist[maxnum],int list[maxnum],int n,int direct,int m) { int flag,k=0; for(int i=0; i<m; i++) { if(visitlist[i]>=n) { flag = i; break; } } if(direct == -1) { for(int i=flag-1; i>-1; i--) { list[k] = visitlist[i]; k++; } for(int j=flag; j<m; j++) { list[k] = visitlist[j]; k++; } } else { for(int i=flag; i<m; i++) { list[k] = visitlist[i]; k++; } for(int j=flag-1; j>-1; j--) { list[k] = visitlist[j]; k++; } } } //对柱面号序列进行从小到大的排序 void bubblesort(int visitlist[],int m) { for(int i=0; i<m; i++) { int temp; for(int j=0; j<m-i-1; j++) { if(visitlist[j]>visitlist[j+1]) { temp = visitlist[j+1]; visitlist[j+1] = visitlist[j]; visitlist[j] = temp; } } } } int main() { int n,m; //n表示当前磁头所在的柱面号;m表示第二行输入m个数 scanf("%d %d",&n,&m); int i,direct; int visitlist[maxnum]; int list[maxnum]; for(i = 0;i < m;i++) scanf("%d",&visitlist[i]); //柱面访问请求序列 scanf("%d",&direct); //移动臂移动方向,-1表示移动臂向柱面号减小方向移动,1表示移动臂向柱面号增大方向移动 bubblesort(visitlist,m); /*for(int i=0;i<m;i++) { printf("%d ",visitlist[i]); } printf("\n"); */ LOOK(visitlist,list,n,direct,m); for(i = 0;i < m;i++) printf("%d ",list[i]); return 0; }
K 存储管理3
题目描述
现有一个8*8的存储器,要对其已分配的空间进行分配及回收。(下标从0开始,最后一个内存块下标为63)。现已有块号为2、7、13、23、37、41、47、59、61的几个内存块被占用。要求输入需分配的进程数M(0<M<=55),接下来输入为M个整型数,每个数为各个进程需占用的内存块数。当分配到某进程时,其剩余空闲块数可以分配,就输出当前进程分配的最后一个内存空间的下标。当分配到某进程时,其进程块数超出剩余空闲块数无法分配,输出为“false”(不含双引号,且为全小写)。输出的多个下标(或"false")之间用空格隔开。以上进程不管是否分配成功,按照输入顺序依次命名为p1、p2、p3………pM。回收的时候输入进程名pN,则返回进程名为pN的所有占用内存块号下标,如果该进程名不存在或输入的数值为不合理范围,则返回“false”。
#include <stdio.h> #include <string.h> #include <stdlib.h> struct Process { int space; //进程申请的内存 int process_number; //进程编号 }; /* *@space 申请的内存 *@s_c[] 已分配的空间表1 *@s_c1[][55] 记录当前程序占用的内存的下标 *@residue 当前剩余的内存空间 *@process_num 当前程序的编号 */ int management(int space,int s_c[],int s_c1[][55],int residue,int process_num) { int i=0,j=0,k=0,count=0,index=0,Final_Index=0; if (space>residue) //申请的内存大于剩余的空间,输出false { printf("false "); return 0; } else { if(space==53) { printf("%d\n",60); for(i=0;i<=60;i++) { if (s_c[i]==0) { s_c1[process_num][j]=i; j++; s_c[i]=1; } } } else if(space>=54) { Final_Index = space+8; printf("%d ",Final_Index); for(i = 0;i <= Final_Index;i++) { if (s_c[i]==0) { s_c1[process_num][j]=i; j++; s_c[i]=1; } } } else { for (i = 0; i < 64; i++) { if (s_c[i]==0) { index=i; goto Next_Process; } } Next_Process: for(i = index;i < index+space+1;i++) { if (s_c[i]==1) { count++; } } for (i = index; i < index+count+space; i++) { if (s_c[i]==0) { Final_Index=i; s_c1[process_num][j]=i; j++; s_c[i]=1; } } printf("%d ", Final_Index); } return 1; } } int main() { int s_c[64]={0}; //初始化内存块 s_c[2]=1; s_c[7]=1; s_c[13]=1; s_c[23]=1; s_c[37]=1; s_c[41]=1; s_c[47]=1; s_c[59]=1; s_c[61]=1; int M; //需分配的进程数M(0<M<=55) scanf("%d",&M); int s_c1[M][55]; //进程占内存的号码 int max_process_number=55; int residue[M]; char reclaim_process[10]; //需回收的进程名 int i; struct Process process[M]; int flag[M][1]; //函数返回值 for (i = 0; i < M; i++) { scanf("%d",&process[i].space); residue[i]=max_process_number; if (max_process_number>process[i].space) { max_process_number-=process[i].space; } process[i].process_number = i+1; } scanf("%s",&reclaim_process); for (i = 0; i < M; i++) { flag[i][0] = management(process[i].space,s_c,s_c1,residue[i],i); } printf("\n"); int reclaim_process_num = reclaim_process[1]-48; for(int i=reclaim_process_num-1;;) { if(flag[reclaim_process_num-1][0]==0) { printf("false"); } else { for(int j=0;j<process[i].space;j++) { int k = s_c1[i][j]; s_c[k] = 0; printf("%d ",k); } } break; } return 0; }
I 存储管理1
题目描述
现有一个8*8的存储器,要对其空间进行分配。(下标从0开始,最后一个内存块下标为63)。现已有块号为1、7、13、23、47、59的几个内存块被占用。现操作系统要求申请N块内存空间(0<N<=64),当输入的块数N超出其剩余空闲块数的时候,输出为“false”,当输入为合理范围的时候,就输出其以行主序分配的最后一个内存空间的下标。
#include <stdio.h> int main() { int s_c[64]={0}; int i,n,count=0; s_c[1]=1; s_c[7]=1; s_c[13]=1; s_c[23]=1; s_c[47]=1; s_c[59]=1; scanf("%d",&n); if(n==1) printf("0"); else if(n>58) printf("false"); else { for(i=0;i<n+1;i++) { if (s_c[i]==1) { count++; } } printf("%d", count+n-1); } return 0; }
C 死锁—利用银行家算法判断系统的安全性c
题目描述
假设系统中有A、B、C三类资源,且有四个并发进程,要求输入资源总量Resource,以及每个进程运行所需的资源总量Claim和已经分配得到的资源量Allocation,利用银行家算法判断当前状态是否为安全状态,若为安全状态则给出一个安全序列。
#include<stdio.h> #include<stdlib.h> struct Process{ char Process_Name[10]; //进程名 int Claim[3]; //每个进程运行所需的资源总量 int Allocation[3]; //已经分配得到的1资源量 int Need[3]; //进程当前所需要的资源 }; int main() { int Resource[3]; //A、B、C三类资源的总数向量 int Available[3]; //系统中每类资源当前可用量 struct Process process[4]; int i,j,k=0,m,n; for(i=0;i<3;i++) scanf("%d",&Resource[i]); for(i=0; i<4; i++) { for(j=0; j<7; j++) { if(j == 0) scanf("%s",&process[i].Process_Name); else if(j<4) scanf("%d",&process[i].Claim[j-1]); else scanf("%d",&process[i].Allocation[j-4]); } } //初始化进程需要的资源向量 for(i=0;i<4;i++) { for(j=0;j<3;j++) { process[i].Need[j] = process[i].Claim[j]-process[i].Allocation[j]; } } for(i=0;i<3;i++) { int sum = 0; for(j=0;j<4;j++) { sum+=process[j].Allocation[i]; } Available[i]=Resource[i]-sum; } int Work[3]; //工作向量 int Temp[4]; //存放安全序列编号 int Finish[4]; //1:当前进程安全 0:不安全 for(i=0;i<4;i++) Finish[i]=0; for(i=0;i<3;i++) Work[i]=Available[i]; //初始化工作向量 for(i=0; i<4; i++) { int flag=0; for(j=0; j<4; j++) { if(flag==1) break; int count=0; for(n=0;n<3;n++) { if(Finish[j]==0 && process[j].Need[n]<=Work[n]) { count++; } if(count==3) //请求的资源都小于剩余的资源数 { flag=1; for(m=0; m<3; m++) { Work[m] += process[j].Allocation[m]; } Finish[j] = 1; //满足的进程置1 Temp[k] = j+1; //记录进程编号 k++; //序列安全+ } } } } if(k!=4) //有一个进程不满足条件,则断言系统不是安全状态,输出"false" { printf("false"); } else //所有进程都满足,断言系统为安全状态,输出安全序列 { for(i=0;i<4;i++) { printf("P%d ",Temp[i]); } } system("pause"); return 0; }
H 进程调度4:时间片轮转
题目描述
要求输入N个进程(0<N<=100),输入时间片M(0<M〈=5),按照进程输入的顺序以时间片轮转的方法输出指定的第K轮(K>0)执行的那个进程的进程名
#include<stdio.h> #include<stdlib.h> struct PROCESS{ char PROCESS_NAME[10]; //进程名 int PTIME; //运行时间 }; int main(){ int M,N,K,Count,Num_Count=0,Final_Num_Count; scanf("%d %d",&M,&N); //输入一个正整数M(0<M<=5)作为时间片 一个正整数N(0<N<=100),接下来输入为N行 struct PROCESS process[N]; int i,j=0,avag_time=0; for(i=0;i<N;i++) scanf("%s %d",&process[i].PROCESS_NAME,&process[i].PTIME); scanf("%d",&K); for (i = 0; i < 100; i++) { while(j<N){ if(process[j].PTIME>0) { process[j].PTIME -= M; Num_Count++; Final_Num_Count=Num_Count; if (Num_Count==K) printf("%s",process[j].PROCESS_NAME); } j++; } j=0; } if(Final_Num_Count < K) printf("over"); }
G 进程调度3
要求输入N个进程(N为正整型数,0<N<=25535),输出按照优先级从高到低执行的进程名字符串序列,直至结束。(如果遇到优先级一样,按照输入顺序先后执行。),本题中,优先数数值较高的进程,优先级也较高。
执行1个时间周期,优先级减1。
#include<stdio.h> #include<stdlib.h> #include<string.h> struct Pros{ char name[10]; //名字 int youxian; //优先级 int time; //运行时间 }pros[25535]; int main(){ int i,j; int n; //进程数 int sum_time=0;//存储运行时间总和 将当做循环的次数使用 int max=-100; //该变量用于找出最大优先级 int cs; //存储优先级最大的进程的下标 ///*输入部分*/// scanf("%d",&n); for(i=0;i<n;i++){ scanf("%s %d %d",pros[i].name,&pros[i].youxian,&pros[i].time); } ///*处理数据*/// for(i=0;i<n;i++){ sum_time=sum_time+pros[i].time; } for(i=0;i<sum_time;i++){ max=-100; //初始化max for(j=0;j<n;j++){ //该循环用于找出优先级最大的进程的下标(若优先级相同则按照输入顺序输出) if(max<pros[j].youxian && pros[j].time>0){ //找出运行时间大于0且优先级最大的数 不使用等号即可保证按照输入顺序输出 max=pros[j].youxian; cs=j; } } if(i<sum_time-1){ //控制输出格式 printf("%s ",pros[cs].name); pros[cs].time--; pros[cs].youxian--; }else{ printf("%s",pros[cs].name); pros[cs].time--; pros[cs].youxian--; } } system("pause"); return 0; }