操作系统实训题目
A、进程调度1-静态非剥夺式优先级调度计算平均作业周转时间
题目描述:
- 要求输入3个进程的信息,假设这些进程均是在0时刻同时到达
- 若进程调度采用非剥夺式静态优先级(优先数数值大的表示优先级比较高;如果遇到优先级一样,按照输入顺序执行)
- 计算并输出平均作业周转时间
输入格式:
- 程序要求输入3行,以回车符号作为分隔每行有3个数据,以空格作为分隔
- 每行对应列的数据:
- 第1列首先输入一个字符串(长度小于等于10),为进程名
- 第2列数据类型为整型,表示进程的优先数
- 第3列数据类型为整型,表示进程的运行时间
输出格式:
输出结果为一个浮点数,保留到小数点后一位,为系统的平均作业周转时间。
测试数据:
样例输入1:
P1 1 1
P2 2 2
P3 3 3
样例输出1:
4.7
具体实现:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
/**
* 思路分析:平均周转时间 = (所有进程运行总时间)/(进程个数)
*/
//维护三个进程,放置数组内
Process p1 = new Process();
Process p2 = new Process();
Process p3 = new Process();
Process[] processes = {p1,p2,p3};
Scanner scanner = new Scanner(System.in);
//输入输出给进程的名字、优先级、时间赋值
for (int i = 0; i < processes.length; i++) {
processes[i].name = scanner.next();
processes[i].priority = scanner.nextInt();
processes[i].time = scanner.nextInt();
}
//按照进程的优先级给进程排序,从大到小
for (int i = 0; i < processes.length - 1; i++) {
for (int j = 0; j < processes.length - 1 - i; j++) {
if (processes[j].priority < processes[j+1].priority)
{
Process tmp = processes[j+1];
processes[j+1] = processes[j];
processes[j] = tmp;
}
}
}
//开始执行
double sum = 0;
double total = 0;
double avgTime = 0;
for (int i = 0; i < processes.length; i++) {
sum = 0;
for (int j = 0; j <= i; j++) {
sum += processes[j].time;
}
total += sum;
}
avgTime = total / processes.length;
//四舍五入保留小数点后一位,平均周转时间avgTime = (double)((int)((avgTime*10)+0.5))/10);
System.out.println((double)((int)((avgTime*10)+0.5))/10);
}
}
class Process{
/**
* 进程名
*/
String name;
/**
* 优先级
*/
Integer priority;
/**
* 运行耗时
*/
Integer time;
}
B、进程调度2-最高响应比优先计算每个作业的周转时间
题目描述:
- 要求输入3个进程的信息,按照最高响应比优先的调度算法计算并输出每个进程的周转时间
- 最高响应比优先调度算法:
- 若两个进程的响应比相同,则优先选择先进入的进程
- 若两个进程的响应比相同,而且进入时刻也相同,则按照输入的顺序执行(如:P4和P6的响应比相同且进入时刻也相同,如P4先输入则选择P4先执行)
- 最高响应比计算公式:
- 第1个进程一定最开始执行
- 第2、第3个进程根据响应比计算谁先执行
- 响应比 = (1 + (前一个进程完成时间 - 当前进程进入时间) / 当前进程运行时间)
- 周转时间 = 完成时间 - 进入时间
输入格式:
程序要求输入3行,以回车符号作为分隔,每行有3个数据,以空格作为分隔。首先输入一个字符串(长度小于等于10),为进程名,第2个数据类型为整型,表示进程的进入时刻,第3个数据类型为整型,表示进程的运行时间。
输出格式:
输出三个整数之间,整数之间用空格作为分隔,为每个进程的周转时间。
测试数据:
样例输入1:
P1 1 1
P2 2 2
P3 3 3
样例输出1:
1 2 4
进程名 | 进入时间 | 开始时间 | 运行时间 | 完成时间 | 响应比 |
---|---|---|---|---|---|
p1 | 1 | 1 | 1 | 2 | |
p2 | 2 | 2 | 2 | 4 | 1 |
p3 | 3 | 4 | 3 | 7 | 2/3 |
p1 周转时间 = 1
p2 周转时间 = 2
p3 周转时间 = 4
具体实现:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Process processOne = new Process();
Process processTow = new Process();
Process processThree = new Process();
//定义数组,存储三个进程
Process[] processes = {processOne,processTow,processThree};
//给进程赋值
for (Process process : processes) {
process.name = scanner.next();
process.enterTime = scanner.nextInt();
process.runningTime = scanner.nextInt();
}
//按进入时间进行排序
for (int i = 0; i < processes.length - 1; i++) {
for (int j = 0; j < processes.length -1 - i; j++) {
if (processes[j+1].enterTime < processes[j].enterTime)
{
Process tmp = processes[j];
processes[j] = processes[j+1];
processes[j+1] = tmp;
}
}
}
//按照最高响应比进行计算
highestResponseRatioAlgorithm(processes);
//输出
System.out.println(processOne.turnaroundTime + " " + processTow.turnaroundTime + " " + processThree.turnaroundTime);
}
private static void highestResponseRatioAlgorithm(Process[] processes) {
//第一个进程开始
processes[0].startTime = processes[0].enterTime;
processes[0].finishTime = processes[0].startTime+processes[0].runningTime;
//开始计算进程2和进程3的响应比
processes[1].responseRatio = 1 + (float)(processes[0].finishTime - processes[1].enterTime)/(processes[1].runningTime);
processes[2].responseRatio = 1 + (float)(processes[0].finishTime - processes[2].enterTime)/(processes[2].runningTime);
//进程2的响应比进程3大,进程2先执行
if (processes[1].responseRatio >= processes[2].responseRatio)
{
//进程2的进入时间比进程1的完成时间还大
if (processes[1].enterTime > processes[0].finishTime)
{
processes[1].startTime = processes[1].enterTime;
processes[1].finishTime = processes[1].startTime + processes[1].runningTime;
//进程3的进入时间比进程2的完成时间还大
if (processes[2].enterTime > processes[1].finishTime)
{
processes[2].startTime = processes[2].enterTime;
}else {
processes[2].startTime = processes[1].finishTime;
}
processes[2].finishTime = processes[2].startTime + processes[2].runningTime;
}else {
//进程2的进入时间等于进程1的完成时间
processes[1].startTime = processes[0].finishTime;
processes[1].finishTime = processes[1].startTime + processes[1].runningTime;
//进程3执行
if (processes[2].enterTime > processes[1].finishTime)
{
processes[2].startTime = processes[2].enterTime;
}else {
processes[2].startTime = processes[1].finishTime;
}
processes[2].finishTime = processes[2].startTime + processes[2].runningTime;
}
}else {
//进程3的响应比进程2大,进程3先执行
//进程3的进入时间比进程1的完成时间还大
if (processes[2].enterTime > processes[0].finishTime)
{
processes[2].startTime = processes[2].enterTime;
processes[2].finishTime = processes[2].startTime + processes[2].runningTime;
if (processes[1].enterTime > processes[2].finishTime)
{
processes[1].startTime = processes[1].enterTime;
}else {
processes[1].startTime = processes[2].finishTime;
}
processes[1].finishTime = processes[1].startTime + processes[1].runningTime;
}else {
processes[2].startTime = processes[0].finishTime;
processes[2].finishTime = processes[2].startTime + processes[2].runningTime;
//进程2的进入时间比进程3的还大
if (processes[2].finishTime < processes[1].enterTime)
{
processes[1].startTime = processes[1].enterTime;
}else {
processes[1].startTime = processes[2].finishTime;
}
processes[1].finishTime = processes[1].startTime + processes[1].runningTime;
}
}
//周转时间=完成时间-进入时间
processes[0].turnaroundTime = processes[0].finishTime - processes[0].enterTime;
processes[1].turnaroundTime =processes[1].finishTime - processes[1].enterTime;
processes[2].turnaroundTime =processes[2].finishTime - processes[2].enterTime;
}
}
class Process{
/**
* 进程名
*/
public String name;
/**
* 进入时间
*/
public int enterTime;
/**
* 运行时间
*/
public int runningTime;
/**
* 开始运行时间
*/
public int startTime;
/**
* 完成时间
*/
public int finishTime;
/**
* 响应比
*/
public float responseRatio;
/**
* 周转时间
*/
public int turnaroundTime;
}
拓展:
以下是一个可以处理不定数量进程的完整实现,实现了最高响应比优先调度算法来计算每个进程的周转时间:
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
List<Process> processes = new ArrayList<>();
// 输入进程信息
for (int i = 0; i < 4; i++) { // 修改为适应更多进程
Process process = new Process();
process.name = scanner.next();
process.enterTime = scanner.nextInt();
process.runningTime = scanner.nextInt();
processes.add(process);
}
// 按照进入时间进行排序
processes.sort(Comparator.comparingInt(p -> p.enterTime));
// 计算最高响应比优先调度算法
highestResponseRatioAlgorithm(processes);
// 输出每个进程的周转时间
for (Process process : processes) {
System.out.print(process.turnaroundTime + " ");
}
}
private static void highestResponseRatioAlgorithm(List<Process> processes) {
Process currentProcess = processes.get(0);
currentProcess.startTime = currentProcess.enterTime;
currentProcess.finishTime = currentProcess.startTime + currentProcess.runningTime;
for (int i = 1; i < processes.size(); i++) {
Process nextProcess = processes.get(i);
float responseRatioCurrent = 1 + (float) (currentProcess.finishTime - nextProcess.enterTime) / nextProcess.runningTime;
float responseRatioNext = 1;
if (i + 1 < processes.size()) {
responseRatioNext = 1 + (float) (currentProcess.finishTime - processes.get(i + 1).enterTime) / processes.get(i + 1).runningTime;
}
if (responseRatioCurrent >= responseRatioNext) {
nextProcess.startTime = nextProcess.enterTime > currentProcess.finishTime ? nextProcess.enterTime : currentProcess.finishTime;
nextProcess.finishTime = nextProcess.startTime + nextProcess.runningTime;
currentProcess = nextProcess;
} else {
nextProcess.startTime = currentProcess.finishTime;
nextProcess.finishTime = nextProcess.startTime + nextProcess.runningTime;
}
}
// 计算周转时间
for (Process process : processes) {
process.turnaroundTime = process.finishTime - process.enterTime;
}
}
}
class Process {
public String name;
public int enterTime;
public int runningTime;
public int startTime;
public int finishTime;
public int turnaroundTime;
}
这个实现可以动态处理不定数量的进程,通过输入来决定处理的进程数目,然后根据最高响应比优先调度算法计算每个进程的周转时间,并输出结果。
C、死锁-利用银行家算法判断系统的安全性
题目描述:
假设系统中有A、B、C三类资源,且有四个并发进程,要求输入资源总量Resource,以及每个进程运行所需的资源总量Claim和已经分配得到的资源量Allocation,利用银行家算法判断当前状态是否为安全状态,若为安全状态则给出一个安全序列
输入格式:
- 程序要求输入五行,以回车符号作为分隔:
- 第一行是三个整数,整数之间以空格作为分隔,表示A、B、C三类资源的总量
- 下面的四行分别表示每个进程运行所需的资源总量Claim和已经分配得到的资源量Allocation,每行有7个数据,以空格作为分隔
- 第1个输入一个字符串(长度小于等于10),为进程名
- 第2、3、4个数据类型为整型,表示相应进程运行所需A、B、C三种资源总量Claim
- 第5、6、7个数据类型为整型,表示相应进程已经分配得到的A、B、C三种资源量Allocation
输出格式:
- 输出一个字符串。若当前为不安全状态则输出为
false
- 若当前为安全状态则输出一个安全序列,进程名之间用空格作为分隔)
测试数据:
样例输入1:
9 5 7
P1 5 3 4 2 1 3
P2 9 5 2 2 1 1
P3 3 2 2 2 2 1
P4 6 4 1 1 1 1
样例输出1:
P3 P1 P4 P2
具体实现:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//A、B、C三类资源
int[] resource = new int[3];
//当前可用资源
int[] available = new int[3];
//定义四个进程
Process[] processes = new Process[4];
int total = 0;
//给A、B、C三类资源赋值
for (int i = 0; i < resource.length; i++) {
resource[i] = scanner.nextInt();
}
//给四个进程赋值,分配资源
for (int i = 0; i < processes.length; i++) {
processes[i] = new Process();
//进程名
processes[i].name = scanner.next();
processes[i].no = i+1;
for (int j = 0; j < 3; j++) {
//所需资源
processes[i].claims[j] = scanner.nextInt();
}
for (int j = 0; j < 3; j++) {
//已得到的资源
processes[i].allocations[j] = scanner.nextInt();
}
}
//初始化进程所需要的资源
for (int i = 0; i < processes.length; i++) {
for (int j = 0; j < 3; j++) {
processes[i].needs[j] = processes[i].claims[j] - processes[i].allocations[j];
}
}
//得到可用的资源和资源总量
for (int i = 0; i < 3; i++) {
int totalResource = 0;
for (int j = 0; j < 4; j++) {
totalResource += processes[j].allocations[i];
}
available[i] = resource[i] - totalResource;
}
//工作向量
int[] work = new int[3];
//安全序列
int[] temp = new int[4];
//每个进程是否安全 1安全 0不安全
int[] finish = new int[4];
System.arraycopy(available, 0, work, 0, work.length);
for (int i = 0; i < 4; i++) {
boolean flag = false;
for (int j = 0; j < 4; j++) {
if (flag)
{
break;
}
int count = 0;
for (int k = 0; k < 3; k++) {
if (finish[j] == 0 && processes[j].needs[k] <= work[k])
{
count++;
}
if (count == 3)
{
flag = true;
for (int l = 0; l < 3; l++) {
work[l] += processes[j].allocations[l];
}
finish[j] = 1;
temp[total] = j+1;
total++;
}
}
}
}
if (total != 4)
{
System.out.println("false");
}else {
for (int i = 0; i < 4; i++) {
System.out.print(temp[i]+" ");
}
System.out.println();
for (int i = 0; i < 4; i++) {
System.out.print(processes[temp[i]-1].name+" ");
}
}
}
}
class Process{
/**
* 进程编号
*/
int no;
/**
* 进程名
*/
public String name;
/**
* 每个进程运行所需要的资源棕榈
*/
public final int[] claims = new int[3];
/**
* 以及分配到的资源量
*/
public final int[] allocations = new int[3];
/**
* 需要分发的资源
*/
public final int[] needs = new int[3];
}
封装后:
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 输入资源总量
int[] resources = new int[3];
for (int i = 0; i < 3; i++) {
resources[i] = scanner.nextInt();
}
// 输入每个进程的Claim和Allocation
int[][] maxClaim = new int[4][3];
int[][] allocation = new int[4][3];
for (int i = 0; i < 4; i++) {
String processName = scanner.next();
for (int j = 0; j < 3; j++) {
maxClaim[i][j] = scanner.nextInt();
}
for (int j = 0; j < 3; j++) {
allocation[i][j] = scanner.nextInt();
}
}
if (isSafeState(resources, maxClaim, allocation)) {
// 如果是安全状态,输出安全序列
System.out.println("安全序列:");
String safeSequence = getSafeSequence(resources, maxClaim, allocation);
System.out.println(safeSequence);
} else {
// 如果不是安全状态,输出false
System.out.println("false");
}
}
// 检查是否为安全状态的方法
public static boolean isSafeState(int[] resources, int[][] maxClaim, int[][] allocation) {
int[] available = Arrays.copyOf(resources, resources.length);
boolean[] finished = new boolean[4];
int count = 0;
while (count < 4) {
boolean safe = false;
for (int i = 0; i < 4; i++) {
if (!finished[i] && canAllocate(resources, allocation[i], available)) {
// 如果有进程可以安全分配资源
safe = true;
finished[i] = true;
count++;
for (int j = 0; j < 3; j++) {
available[j] += allocation[i][j];
}
}
}
if (!safe) {
return false; // 没有进程可以安全分配资源,不是安全状态
}
}
return true; // 所有进程都能安全完成,是安全状态
}
// 检查是否可以分配资源给进程的方法
public static boolean canAllocate(int[] resources, int[] request, int[] available) {
for (int i = 0; i < 3; i++) {
if (request[i] > resources[i] || request[i] > available[i]) {
return false;
}
}
return true;
}
// 获取安全序列的方法
public static String getSafeSequence(int[] resources, int[][] maxClaim, int[][] allocation) {
int[] available = Arrays.copyOf(resources, resources.length);
boolean[] finished = new boolean[4];
StringBuilder sequence = new StringBuilder();
int count = 0;
while (count < 4) {
boolean safe = false;
for (int i = 0; i < 4; i++) {
if (!finished[i] && canAllocate(resources, maxClaim[i], available)) {
safe = true;
finished[i] = true;
count++;
for (int j = 0; j < 3; j++) {
available[j] += allocation[i][j];
}
sequence.append("P").append(i + 1).append(" ");
}
}
if (!safe) {
break;
}
}
return sequence.toString();
}
}
D、存储管理-可变分区存储管理方式的最佳适应分配算法
题目描述:
当内存管理采用可变分区分配方案时,要求输入多个空闲分区和进程内存请求序列,输出显示采用最佳适应分配算法分配给各个进程的分区编号
输入格式:
- 程序要求输入3行,以回车符号作为分隔
- 第1行是一个整数n(n >=3 ),表示空闲分区的数量
- 第2行是n个整数,依次按地址递增对应第一行n个空闲分区的存储容量,每个整型数的数值代表所对应空间的剩余存储容量。n个分区(分区按地址递增依次从1开始编号,若分区X被切割分配了,剩余部分即使为0也保留原来的分区编号X)
- 第3行是3个整数,两个数之间以空格作为分隔,分别表示三个进程先后依次申请的内存空间的大小
输出格式:
输出一行三个整数,整数之间用空格作为分隔,分别表示三个进程所分配的分区编号;若分配失败,则用false
表示
测试数据:
样例输入1:
6
20 5 6 18 60 4
12 7 20
样例输出1:
4 1 5
具体实现:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
if (n < 3)
{
return;
}
Memory[] memories = new Memory[n];
//三个进程申请的内存空间的大小
int[] processes = new int[3];
//给n个内存分区分配空间
for (int i = 0; i < memories.length; i++) {
memories[i] = new Memory();
memories[i].storeSpace = scanner.nextInt();
memories[i].no = i+1;
}
//给进程分配内存空间
for (int i = 0; i < processes.length; i++) {
processes[i] = scanner.nextInt();
}
//用于记录当前执行的线程
int sign = 0;
for (int i = 0; i < 3; i++) {
sign = -1;
//按存储空间升序排序
sortByStoreSpace(memories);
for (int j = 0; j < memories.length; j++) {
if (memories[j].storeSpace >= processes[i])
{
sign = memories[j].no;
memories[j].storeSpace -= processes[i];
break;
}
}
if (sign == -1)
{
System.out.print("false ");
}else {
System.out.print(sign+" ");
}
}
}
/**
* 该方法用于根据存储空间给内存分区排序 升序
* @param memories 内存
*/
private static void sortByStoreSpace(Memory[] memories) {
for (int i = 0; i < memories.length - 1; i++) {
for (int j = 0; j < memories.length -1 -i; j++) {
if (memories[j].storeSpace > memories[j+1].storeSpace)
{
Memory tmp = memories[j];
memories[j] = memories[j+1];
memories[j+1] = tmp;
}
}
}
}
}
class Memory{
/**
* 分区编号
*/
public int no;
/**
* 存储空间的容量
*/
public int storeSpace;
}
E、存储管理-FIFO页面替换算法计算中断次数
题目描述:
在请求分页式存储管理方式中,要求输入一个对5个页面的访问序列,输出当系统分配给进程物理页框数为m个时,按照FIFO页面替换算法的缺页中断次数(假设初始时页框均为空)
输入格式:
- 程序要求输入3行,以回车符号作为分隔
- 第1行是一个整数 n ,表示页面访问序列中访问页面的次数
- 第2行是 n 个整数,数之间以空格作为分隔,表示页面访问序列
- 第3行是一个整数 m ,表示系统分配给进程物理页框数
输出格式:
输出一个整数,表示缺页中断次数。
测试数据:
样例输入1:
12
4 3 2 1 4 3 5 4 3 2 1 5
3
样例输出1:
9
具体实现:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] a = new int[n];
for (int i = 0; i < a.length; i++) {
a[i] = scanner.nextInt();
}
int m = scanner.nextInt();
int[] b = new int[m];
Arrays.fill(b, 32767);
int count = fifo(a,b,m,n);
System.out.println(count);
}
private static int fifo(int[] a, int[] b, int m, int n) {
int count = 0;
int j = 0;
int k = 0;
for (int i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
if (a[i] == b[j])
{
break;
}
}
if (j == m)
{
for (k = 0; k < m - 1; k++) {
b[k] = b[k+1];
}
b[k] = a[i];
count++;
}
}
return count;
}
}
F、驱动调度-采用电梯调度算法排列出磁盘请求响应次序
题目描述:
要求输入一个柱面访问请求序列以及当前磁头所在柱面号和移动方向,输出采用电梯调度算法时移动臂响应的柱面访问序列
输入格式:
- 程序要求输入3行,以回车符号作为分隔
- 第1行是2个整数n、m,之间用空格隔开,n表示当前磁头所在的柱面号;m表示第二行输入m个数
- 第2行是m个整数,数之间以空格作为分隔,表示柱面访问请求序列
- 第3行是数字 -1 或 1,当为 -1 时表示移动臂向柱面号减小方向移动,当为 1 时表示移动臂向柱面号增大方向移动
输出格式:
输出m个整数,数之间以空格作为分隔,采用电梯调度算法时移动臂响应的柱面访问序列。
测试数据:
样例输入1:
15 10
24 38 2 110 43 36 5 11 6 180
-1
样例输出1:
11 6 5 2 24 36 38 43 110 180
具体实现:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] memories = new int[64];
//有些已经占掉了
memories[1] = 1;
memories[7] = 1;
memories[13] = 1;
memories[23] = 1;
memories[47] = 1;
memories[59] = 1;
int n = scanner.nextInt();
if (n == 1)
{
System.out.println(0);
}else if (n > 58)
{
System.out.println(false);
} else {
int num = 0;
for (int i = 0; i < n; i++) {
if (memories[i] == 1)
{
num++;
}
}
System.out.println(n+num-1);
}
}
}
G、进程调度3
题目描述:
要求输入N个进程(N为正整型数,0 < N <= 25535),输出按照抢占式优先级从高到低执行的进程名字符串序列,直至结束。(如果遇到优先级一样,按照输入顺序先后执行。),本题中,优先数数值较高的进程,优先级也较高。进程每运行一个时间单位,优先数-1
输入格式:
- 程序首先要求输入一个整型变量N,接下来输入为N行,以回车符号作为分隔
- 每行有3个数据,以空格作为分隔:
- 第1个输入一个字符串(长度小于等于10),该字符串为进程名
- 第2个数据类型为整型,表示进程的优先数
- 第3个数据类型为整型,表示进程的运行时间
输出格式:
输出1行,M个字符串,字符串之间用空格作为分隔。
测试数据:
样例输入1:
3
P1 1 1
P2 2 2
P3 3 3
样例输出1:
P3 P2 P3 P1 P2 P3
具体实现:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//输入的进程长度必须再(0-25535]
int length = 0;
do {
length = scanner.nextInt();
}while (!(length > 0 && length <= 25535));
Process[] processes = new Process[length];
for (int i = 0; i < processes.length; i++) {
processes[i] = new Process();
processes[i].name = scanner.next();
processes[i].priority = scanner.nextInt();
processes[i].time = scanner.nextInt();
processes[i].no = i+1;
}
test(processes);
}
private static void test(Process[] processes) {
int sumTime = 0;
for (int i = 0; i < processes.length; i++) {
sumTime += processes[i].time;
}
int max = processes[0].priority;
String print = processes[0].name;
for (int i = 0; i < sumTime; i++) {
for (int j = 0; j < processes.length; j++) {
if (processes[j].time > 0 && (processes[j].priority > max))
{
max = processes[j].priority;
print = processes[j].name;
}
}
for (int j = 0; j < processes.length; j++) {
if (processes[j].name.equals(print))
{
System.out.print(processes[j].name+" ");
processes[j].priority--;
processes[j].time--;
}
}
max = processes[0].priority;
print = processes[0].name;
}
}
}
/**
* 该类为进程类
*/
class Process{
public int no;
/**
* 进程名
*/
public String name;
/**
* 优先级
*/
public int priority;
/**
* 运行耗时
*/
public int time;
}
H、进程调度4-时间片轮转
题目描述:
要求输入N个进程(0 < N <= 100),输入时间片M(0 < M <=5),按照进程输入的顺序以时间片轮转的方法输出指定的第 K 轮(K > 0)执行的那个进程的进程名
输入格式:
- 第一行:程序首先输入一个正整数M回车(0 < M <= 5)作为时间片
- 第二行:输入一个正整数N回车(0 < N <= 100),接下来输入为N行,以回车符号作为分隔,每行有2个数据,以空格作为分隔。
- 第1个数据是字符串(长度小于等于10),该字符串为进程名
- 第2个数据类型为整型,表示该进程需要的运行时间。最后输入一个正整数K,作为时间片轮转的次数(次数从1开始计数)
输出格式:
- 输出一个字符串,为最后执行进程的进程名
- 若无进程运行,则输出
over
测试数据:
样例输入1:
1
3
P1 1
P2 2
P3 3
3
样例输出1:P3
具体实现:
import java.util.Scanner;
/**
* @Author: SayHello
* @Date: 2022/11/2 9:49
* @Version: 1.0
* @Introduction:
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//时间片(0,5]
int m = 0;
//输入进程个数(0,100]
int n = 0;
//时间片轮转次数
int k = 0;
int numCount = 0;
int finalCount = 0;
do {
m = scanner.nextInt();
}while (!(m > 0 && m <= 5));
do {
n = scanner.nextInt();
}while (!(n> 0 && n <= 100));
Process[] processes = new Process[n];
for (int i = 0; i < processes.length; i++) {
processes[i] = new Process();
processes[i].name = scanner.next();
processes[i].time = scanner.nextInt();
}
do {
k = scanner.nextInt();
}while (!(k > 0));
for (int i = 0; i < 100; i++) {
for (int j = 0; j < processes.length; j++) {
if (processes[j].time > 0)
{
processes[j].time = processes[j].time - m;
finalCount = ++numCount;
if (numCount == k)
{
System.out.println(processes[j].name);
}
}
}
}
if (finalCount < k)
{
System.out.println("over");
}
}
}
class Process{
/**
* 进程名
*/
String name;
/**
* 运行时间
*/
Integer time;
}
I、存储管理1
题目描述:
- 现有一个 8 * 8 的存储器,要对其空间进行分配。(下标从0开始,最后一个内存块下标为63)。
- 现已有块号为1、7、13、23、47、59 的几个内存块被占用。现操作系统要求申请 N 块内存空间(0 < N <= 64)
- 当输入的块数 N 超出其剩余空闲块数的时候,输出为
false
- 当输入为合理范围的时候,就输出其以行主序分配的最后一个内存空间的下标。
- 当输入的块数 N 超出其剩余空闲块数的时候,输出为
输入格式:
程序要求输入一个整型数N,表示要申请分配空间的大小。
输出格式:
输出为一个整型数,表示最后一个被分配空间的下标。
测试数据:
样例输入1:
3
样例输出1:
3
具体实现:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] memories = new int[64];
//有些已经占掉了
memories[1] = 1;
memories[7] = 1;
memories[13] = 1;
memories[23] = 1;
memories[47] = 1;
memories[59] = 1;
int n = scanner.nextInt();
if (n == 1)
{
System.out.println(0);
}else if (n > 58)
{
System.out.println(false);
} else {
int num = 0;
for (int i = 0; i < n; i++) {
if (memories[i] == 1)
{
num++;
}
}
System.out.println(n+num-1);
}
}
}
J、存储管理2
题目描述:
- 现有一个8 * 8的存储器,要对其空间进行分配。(下标从0开始,最后一个内存块下标为63)
- 现已有块号为2、7、13、23、37、47、59、61的几个内存块被占用。要求输入需分配的进程数M(0 < M <= 56),接下来输入为M个整型数,每个数为各个进程需占用的内存块数
- 当分配到某进程时,其剩余空闲块数可以分配,就输出当前进程分配的最后一个内存空间的下标
- 当分配到某进程时,其进程块数超出剩余空闲块数无法分配,输出为
false
- 输出的多个下标(或
false
)之间用空格隔开
输入格式:
- 程序输入分为两行
- 第1行要求输入一个整型数M,表示要所需分配空间的进程数
- 第2行输入M个整型数,每个数之间用空格隔开,表示M个进程每个进程占用的内存空间大小
输出格式:
输出为M组整型数(或false
),每个整型数表示该进程最后一个被分配的内存空间的下标(或false
),下标(或false
)之间用空格隔开。
测试数据:
样例输入1:
3
3 3 3
样例输出1:
3 6 10
具体实现:
import java.util.Scanner;
/**
* @Author: SayHello
* @Date: 2022/11/3 10:29
* @Version: 1.0
* @Introduction: 现有一个8*8的存储器,要对其已分配的空间进行分配及回收。
*/
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int[] memories = new int[64];
//有些已经占掉了
memories[2] = 1;
memories[7] = 1;
memories[13] = 1;
memories[23] = 1;
memories[37] = 1;
memories[47] = 1;
memories[59] = 1;
memories[61] = 1;
int M = scanner.nextInt();
int[] a = new int[M];
//数据输入
for (int i = 0; i < M; i++) {
a[i] = scanner.nextInt();
}
int c = a[0];
for (int i = 0; i < a.length; i++) {
if (a[i] > c) {
System.out.print(false+" ");
continue;
}
c = c + a[i];
for (int j = 0; j <= 63; j++) {
if (memories[j] == 0) {
memories[j] = 1;
a[i]--;
}
if (a[i] == 0) {
System.out.print(j+ " ");
break;
}
}
}
}
}
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
。
输入格式:
- 程序输入分为三行
- 第1行是一个整型数M,表示要所需分配空间的进程数
- 第2行为M个整型数,每个数之间用空格隔开,表示M个进程每个进程占用的内存空间大小
- 第3行为需要回收的进程名pN,p为小写字母,N为正整型数
输出格式:
- 输出为两行
- 第1行为一组整型数,每个整型数表示该进程最后一个被分配的内存空间的下标,下标之间用空格隔开
- 第2行为一组整型数,表示被回收的进程的内存块下标,多个下标之间用空格隔开
测试数据:
样例输入1:
3
3 3 3
p3
样例输出1:
3 6 10
8 9 10
具体实现:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//总内存数量
int[] memories = new int[64];
//有些已经占掉了,共有9个空间被占掉了
memories[2] = 1;
memories[7] = 1;
memories[13] = 1;
memories[23] = 1;
memories[37] = 1;
memories[41] = 1;
memories[47] = 1;
memories[59] = 1;
memories[61] = 1;
//剩余进程数为64-9
int[] processMemory = new int[56];
//记录最后一个被分配的内存空间的下标
int[] indexes = new int[56];
//二维数组,第一维表示是第几个进程,第二维表示的是该进程占用了哪几个内存块
int[][] processAndMemory = new int[56][56];
//统计剩余内存块
int remain = 0;
//总内存个数
int total = memories.length;
//统计已使用的内存个数
int use = 0;
//统计最后一个被分配的内存空间的下标
int lastIndexes = 0;
//统计进程名的数字
int namNum;
/**
* 1、给需要分配空间的进程数
* 2、每个进程占用的内存空间大小
* 3、为需要回收的进程名赋值
*/
//输入带分配内存的进程数
int m = scanner.nextInt();
//输入每个进程所占的内存空间大小
for (int i = 0; i < m; i++) {
processMemory[i] = scanner.nextInt();
}
//输入的进程名
String name = scanner.next();
//统计已用的内存
for (int memory : memories) {
remain += memory;
}
//开始执行
for (int i = 0; i < m; i++) {
if (processMemory[i] <= total - remain)
{
use = 0;
for (int j = 0;j < total - 1 && use < processMemory[i]; j++) {
if (memories[j] == 0 && use < processMemory[i])
{
//内存被使用,修改为1
memories[j] = 1;
//进程已使用的++
use++;
//总共已使用的++
remain++;
//记录已占用内存的索引
indexes[i] = j;
processAndMemory[i][j] = 1;
}
}
System.out.print(indexes[i]+" ");
}else {
System.out.print(false+" ");
}
}
System.out.print("\n");
namNum = count(name);
for (int i = 0; i < processMemory.length; i++) {
lastIndexes += processAndMemory[namNum - 1][i];
}
if(lastIndexes == 0){
System.out.print(false);
return;
}
if(namNum <= m){
for (int i = 0; i < processMemory.length; i++) {
if (processAndMemory[namNum - 1][i] == 1)
{
System.out.print(i+" ");
}
}
System.out.print("\n");
}else{
System.out.print(false);
}
}
/**
* 该方法用于获取进程名的数子
* @param processName PN
* @return 获取N,返回
*/
public static int count(String processName)
{
int count = 0;
char[] chars = processName.toCharArray();
for (int i = 1; i < chars.length; i++) {
count = count * 10 + chars[i] - 48;
}
return count;
}
}
L、带存储管理的处理器调度4
题目描述:
- 现有一个内存为100K的采用位示图进行页面管理的道数不受限制的多道程序设计系统:
- 若作业调度采用高优先级(优先数越大优先级越大)调度算法(如果遇到优先级一样且只能调入一道作业时,按照输入顺序选择调度对象)
- 进程调度采用非剥夺式的SJF调度算法(如果遇到运行时间相同的进程,按照输入顺序选择调度对象)
- 要求输入3个进程信息,输出当三个作业同时提交进入调度时进程的运行顺序
输入格式:
- 程序要求输入3行,以回车符号作为分隔,每行有4个数据,以空格作为分隔。
- 第一个输入一个字符串(长度小于等于10)为进程名
- 第2个数据类型为整型,表示进程所需的内存空间
- 第3个数据类型为整型,表示进程的运行时间
- 第4个数据类型为整型,表示进程的优先数
输出格式:
输出1行,M个字符串,字符串之间用空格作为分隔。
测试数据:
样例输入1:
P1 20 2 1
P2 60 3 2
P3 30 4 3
样例输出1:
P2 P1 P3
具体实现:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
Process[] processes = new Process[3];
//可用内存为100k
int totalMemory = 100;
//当前占用的内存
int currMemory=0;
int minTime;
int minIndex = 0;
//给数组数据赋值
for (int i = 0; i < processes.length; i++) {
processes[i] = new Process();
processes[i].name = scanner.next();
processes[i].memory = scanner.nextInt();
processes[i].time = scanner.nextInt();
processes[i].priority = scanner.nextInt();
//优先级的排名,数字越大,优先级越高
processes[i].priorityRank = 1;
//未进入为状态0 进入等待1 开始运行为2
processes[i].state = 0;
}
//按优先级进行排序,如果优先级相同则不排序,如果不同则排序
if (processes[0].priority != processes[1].priority || processes[0].priority != processes[2].priority || processes[1].priority != processes[2].priority)
{
sortByPriority(processes);
}
for (int i = 0; i < processes.length; i++) {
//找出优先级最大的作业
for (int j = processes.length; j > 0; j--) {
for (int k = 0; k < processes.length; k++) {
if (processes[k].state == 0 && processes[k].priorityRank == j && (currMemory + processes[k].memory) <= totalMemory)
{
currMemory += processes[k].memory;
processes[k].state = 1;
}
}
}
//找出运行时间最短的进程
minTime=101;
for (int j = 0; j < processes.length; j++) {
if (minTime > processes[j].time && processes[j].state == 1)
{
minTime = processes[j].time;
minIndex = j;
}
}
//将已用内存释放
currMemory -= processes[minIndex].memory;
//表示该进程已经运行
processes[minIndex].state = 3;
System.out.print(processes[minIndex].name+" ");
}
}
/**
* 该方法用于找出优先级最大的进程
* @param processes 进程集合
*/
public static void sortByPriority(Process[] processes)
{
for (int i = 0; i < processes.length - 1; i++) {
for (int j = i + 1; j < processes.length; j++) {
if (processes[i].priority > processes[j].priority)
{
processes[i].priorityRank++;
}else {
processes[j].priorityRank++;
}
}
}
}
}
class Process{
/**
* 进程名
*/
String name;
/**
* 所需内存空间
*/
int memory;
/**
* 运行时间
*/
int time;
/**
* 优先级
*/
int priority;
/**
* 优先级排名 3 2 1 优先级越大排名越大
*/
int priorityRank;
/**
* 运行状态
*/
int state;
}