package com.yixin.java;
import java.util.LinkedList;
import java.util.Random;
public class ProcessMemoryScheduling {
private static int PROCESS_NUM = 10; // 进程数
private int blocked = 0; // 阻塞进程的标识,表示是否有进程属于阻塞状态
private int blockIndex = -1; // 阻塞进程的下标,没有阻塞进程则为-1
private PCB[] pcb = new PCB[PROCESS_NUM]; // 进程数组,存放所有进程
private LinkedList<MemoryBlock> memoryBlockList = new LinkedList<>();
private double timeSlice; // 时间片的大小
private int runningIndex; // 当前运行的进程的下标(索引),没有则为-1
private long lastTime; // 每次调度程序都记录当前时间
private long beginTime; // 程序开始运行的时间
/**
* @Description 用于判断所有进程是否运行完
* @Author yixin
*/
private boolean isFinishALLProcess() {
for (int i = 0; i < PROCESS_NUM; i++) {
if (!pcb[i].status.equals("Finish")) {
return false;
}
}
return true;
}
/**
* @Description 初始化测试数据
* @Author yixin
*/
private void initData() {
runningIndex = -1;
Random r = new Random();
for (int n = 0; n < PROCESS_NUM; n++) {
pcb[n] = new PCB();
pcb[n].name = "P" + Integer.toString(n + 1); // 设置进程名
pcb[n].needTime = r.nextDouble() * 4 + 12; // 随机产生服务时间, 4到12秒
pcb[n].needMemory = r.nextInt(122) + 38; // 随机产生需要的内存 ,38到150KB
if (n == 0) {
pcb[n].arriveTime = 0; // 第一个作业默认0时刻到达
pcb[0].needMemory = 50;
} else {
pcb[n].arriveTime = r.nextDouble() * 5 + 1; // 随机设置到达时间
pcb[n].needMemory = r.nextInt(122) + 38; // 随机产生需要的内存 ,38到150KB
}
}
for (int n = 0; n < PROCESS_NUM; n++) {
pcb[n].hasUsedTime = 0;
pcb[n].address = 0;
pcb[n].status = "U";
}
MemoryBlock firstBlock = new MemoryBlock(0, 1024); // 设置用户内存在0到1024之间
memoryBlockList.add(firstBlock);
print();
}
/**
* @Description 精确度位数的截图
* @Author yixin
*/
private String d2s(double d) {
String tmp = d + "";
int index = tmp.indexOf(".");
int EXACT_DIGIT = 1; // double型变量小数点后精确的尾数
return tmp.substring(0, index + EXACT_DIGIT + 1);
}
/**
* @Description 一次划分算法,为快排做准备
* @Author yixin
*/
private int getStandard(int i, int j) {
PCB key = pcb[i]; // 基准数据
while (i < j) {
// 因为默认基准是从左边开始,所以从右边开始比较
// 当队尾的元素大于等于基准数据 时,就一直向前挪动 j 指针
while (i < j && pcb[j].arriveTime >= key.arriveTime) {
j--;
}
// 当找到比 array[i] 小的时,就把后面的值 array[j] 赋给它
if (i < j) {
pcb[i] = pcb[j];
}
// 当队首元素小于等于基准数据 时,就一直向后挪动 i 指针
while (i < j && pcb[i].arriveTime <= key.arriveTime) {
i++;
}
// 当找到比 array[j] 大的时,就把前面的值 array[i] 赋给它
if (i < j) {
pcb[j] = pcb[i];
}
}
// 跳出循环时 i 和 j 相等,此时的 i 或 j 就是 key 的正确索引位置
// 把基准数据赋给正确位置
pcb[i] = key;
return i;
}
/**
* @Description 根据到达时间使用快排算法进行排序
* @Author yixin
*/
private void quickSortByArriTime(int low, int high) {
// 开始默认基准为 low
if (low < high) {
int standard = getStandard( low, high); // 分段位置下标
quickSortByArriTime( low, standard - 1); // 左边排序
quickSortByArriTime(standard + 1, high); // 右边排序
}
}
/**
* @Description 结果显示函数
* @Author yixin
*/
private void print() {
System.out.println("\n-----------------------------------------------------------------------------");
System.out.println("内存分区表(Busy:占用 Free:空闲):");
System.out.println("起址(K) 长度(KB) 状态");
for (MemoryBlock memoryBlock : memoryBlockList) {
System.out.printf("%-8d %-10d %-6s\n", memoryBlock.address, memoryBlock.length, memoryBlock.status);
}
/* 打印后备队列中的作业 */
System.out.println("\n后备队列中的作业:");
for (int i = 0; i < PROCESS_NUM; i++) {
if (pcb[i].status.equals("U")) {
System.out.print(pcb[i].name + "\t");
}
}
/* 打印就绪队列、运行中、阻塞状态、完成调度这几个状态的进程 */
System.out.println("\n当前各进程PCB信息:");
System.out.print("进程名 到达时间/s 需要时间/s 已用时间/s 所需内存/KB 内存起址 进程状态\n");
for (int i = 0; i < PROCESS_NUM; i++) {
if (!pcb[i].status.equals("U")) {
System.out.printf("%-6s %-10s %-10s %-10s %-11d %-8d %-8s\n", pcb[i].name, d2s(pcb[i].arriveTime)
, d2s(pcb[i].needTime), d2s(pcb[i].hasUsedTime), pcb[i].needMemory, pcb[i].address, pcb[i].status);
}
}
System.out.println("-----------------------------------------------------------------------------");
lastTime = System.currentTimeMillis(); // 更新上次调度时间
}
/**
* @Description 获取后续等待进程信息
* @Author yixin
*/
private int getNextWaiting(int curr) {
int p = curr;
while ((p = ++p % PROCESS_NUM) != curr) {
if (pcb[p].status.equals( "Waiting") ) {
return p;
}
}
return -1;
}
/**
* @Description 从后备队列中选择作业并申请内存
* @Author yixin
*/
private void getNextOnDisk(double allTime) {
int memoryProcessNum = 0; // 在内存中的进程个数
for (PCB aPcb : pcb) {
if (aPcb.status.equals("Waiting") || aPcb.status.equals("Running") || aPcb.status.equals("Blocking")) {
memoryProcessNum++;
}
}
int MAX_OCCURS = 5; // 允许并发的进程数量,小于这个数时从后备队列调入进程
if (memoryProcessNum < MAX_OCCURS) { // 如果内存中程序数少于最大并发数,从后备队列找到最先到达的进程调入内存
for (int p = 0; p < pcb.length && memoryProcessNum < MAX_OCCURS; p++) {
if (pcb[p].status.equals("U") && allTime >= pcb[p].arriveTime) {
int address = applyMemory(p);
if (address != -2) { // 分配内存成功才修改状态
pcb[p].address = address;
pcb[p].status = "Waiting";
memoryProcessNum++;
}
}
}
}
}
/**
* @Description 申请内存
* @Author yixin
*/
private int applyMemory(int curr) {
if (!pcb[curr].status.equals("U")) {
return -2;
}
MemoryBlock target
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
一、语言及软件环境:Java、Windows 11, JDK1.8,IntelliJ IDEA 二、课程设计内容和要求: 1、提交一批作业(>=10),按先来先服选择一部分作业(最多5个)进入内存。 2、为每个作业创建一个进程,并分配内存(用户内存:0—1024K,采用可变连续分配方式)。 3、进程调度功能(时间片轮转)。 4、随机阻塞进程,并在一段时间后唤醒进程(选做)。 5、显示相关信息:后备作业队列、内存分配情况、进程信息、完成作业情况。 6、这些功能要有机地连接起来。 三、设计需求分析: 1、使用随机数初始化10个作业,放入到后备队列中,然后使用先来先服务(FCFS)进行作业调度,最多只能有5个作业同时进入内存。 2、假设阻塞状态的进程仍然在内存中,则处于就绪、运行,阻塞三种状态的进程总数目最多为5个,即并发进程总数最多为5个,在进程结束后,就会被调出内存,同时继续使用先来先服务算法从后备队列中调入新的作业。 (参考可以,抄袭请自重)
资源推荐
资源详情
资源评论
收起资源包目录
2022年广工操作系统课设(源代码+课设报告).zip (15个子文件)
操作系统课程设计.docx 1.16MB
OSCourseDesign
src
com
yixin
java
PCB.java 468B
MemoryBlock.java 395B
ProcessMemoryScheduling.java 15KB
Main.java 241B
.idea
misc.xml 273B
modules.xml 268B
dictionaries
Administrator.xml 157B
workspace.xml 20KB
inspectionProfiles
Project_Default.xml 1KB
out
production
OSCourseDesign
com
yixin
java
ProcessMemoryScheduling.class 8KB
Main.class 523B
PCB.class 426B
MemoryBlock.class 465B
OSCourseDesign.iml 423B
共 15 条
- 1
资源评论
- zzkq111232022-07-10非常有用的资源,有一定的参考价值,受益匪浅,值得下载。
- hgcvg2023-05-08简直是宝藏资源,实用价值很高,支持!
- 「已注销」2022-07-08发现一个宝藏资源,赶紧冲冲冲!支持大佬~
昵称只能一个月修改一次呀
- 粉丝: 686
- 资源: 11
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功