操作系统实验二——cpu调度与内存分页
操作系统实验报告(读者写着问题,时间片轮转算法,内存的分配,进程的调度)
电子科技大学计算机学院实验中心小心计算机专业类课程实验报告课程名称:操作系统学 院:软件学院专 业:软件工程学生姓名:李 希学 号:2010231020018指导教师:丁老师日 期: 2012年5月5日电子科技大学实验报告实验一一、实验名称:进程管理二、实验学时:4三、实验内容和目的:实验内容:(1)进程的创建写一段源程序,创建两个进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。
让每一个进程在屏幕上显示字符。
观察纪录屏幕上的显示结果,然后分析原因。
(2)进程的控制修改编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕出现的现象,并分析原因。
实验目的:(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
(3)分析进程竞争资源现象,学习解决进程互斥的方法。
四、实验原理:利用fork函数来创建子进程,并返回子进程的ID号。
利用lockf函数来实现信号量对进程的资源竞争的调度,和互斥的方法。
五、实验器材(设备、元器件):一台装有VS2010的电脑,操作系统为WIN7.六、实验步骤:(1)先写好2个子进程程序,并且让2个子程序在屏幕上分别打印出A,B(2)父进程创建2个子进程,并在屏幕上打印出C。
(3)观察进程竞争资源的现象。
七、实验数据及结果分析:电子科技大学计算机学院实验中心子进程A的代码:#include<iostream>#include<windows.h>using namespace std;int main(){cout<<"I'm Process A/n"<<endl;return 0;}子进程B的代码:#include<iostream>using namespace std;int main(){cout<<"I'm Process B"<<endl;;return 0;}父进程C的代码://#include "stdafx.h"#include<windows.h>#include<iostream>using namespace std;void print_error(){DWORD nErrorNo = GetLastError ( );LPSTR lpBuffer;FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS |FORMAT_MESSAGE_FROM_SYSTEM,NULL,nErrorNo,LANG_NEUTRAL,(LPTSTR) & lpBuffer,0 ,NULL );if (lpBuffer == NULL){lpBuffer = "Sorry, cannot find this error info. ";}printf("%s (%d).\n", lpBuffer, nErrorNo);}int fork(const char* pszApplication,HANDLE& hProcess){STARTUPINFO si={sizeof(si)};PROCESS_INFORMATION pi;if(!CreateProcess(pszApplication,NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,&pi)) return -1;else{hProcess=pi.hProcess;return pi.dwProcessId;}}void lockf(HANDLE hObj){DWORD state = WaitForSingleObject(hObj,INFINITE);switch (state){case WAIT_OBJECT_0:printf("\nProcess exit.\n");break;case WAIT_TIMEOUT:printf("\nTime out.\n");break;case WAIT_FAILED:printf("\nWait Failed.\n");print_error();break;}}int main(int argc, char* argv[]){HANDLE hProcess1,hProcess2;int child1=fork("C:\\操¨´作Á¡Â系¦Ì统ª3实º¦Ì验¨¦\\ProcessA\\Debug\\ProcessA.exe",hProcess1);if(-1==child1){cout << "fork error!\n";return -1;}lockf(hProcess1);电子科技大学计算机学院实验中心int child2=fork("C:\\操¨´作Á¡Â系¦Ì统ª3实º¦Ì验¨¦\\ProcessB\\Debug\\ProcessB.exe",hProcess2);if(-1==child2){cout << "fork error!\n";return -1;}cout<<"This is Process C\n";lockf(hProcess2);return 0;}程序运行的结果:八、实验结论、心得体会和改进建议:实验结论:成功的通过了父进程C来创建了2个子进程A,B,并成功的对子进程进行了调度与管理。
操作系统的内存分页和虚拟内存实现内存的分页和虚拟内存的管理
操作系统的内存分页和虚拟内存实现内存的分页和虚拟内存的管理操作系统中的内存管理是计算机系统中至关重要的一部分。
在大部分计算机系统中,内存被划分为一系列连续的内存块,用于存储正在执行的程序、数据和系统内核。
然而,由于内存容量的限制和多任务操作系统的需要,操作系统需要采取一些技术来实现内存的分页和虚拟内存的管理。
本文将介绍操作系统中内存分页和虚拟内存的实现原理和管理方法。
一、内存分页的实现内存分页是操作系统中一种常见的内存管理技术。
它将物理内存和逻辑内存划分为固定大小的块,称为页。
每个页的大小通常为2的幂,例如4KB或8KB。
当程序加载到内存时,它会被分割成与页大小相匹配的若干页,每个页都被映射到内存中的一个页帧。
这种方式可以提高内存的利用率,减少碎片化问题。
在内存分页的实现中,操作系统会维护一个页表来跟踪每个页的映射情况。
页表中的每个表项包含了页号和页帧号的对应关系。
当程序需要访问一个逻辑地址时,操作系统先通过页表查找对应的页帧号,然后将逻辑地址转换为物理地址,最后将数据加载到内存中。
内存分页的实现需要支持页表的生成和维护,还需要处理内存地址的转换和访问权限的控制。
操作系统通常会使用硬件中的内存管理单元(MMU)来加速地址转换的过程。
MMU可以通过页表的基址寄存器和逻辑地址的偏移量,直接计算出物理地址,提高地址转换的效率。
二、虚拟内存的实现虚拟内存是一种在物理内存不足的情况下,将部分数据存储到磁盘上的技术。
它为每个进程提供了独立的地址空间,使得每个进程感觉自己独占了整个内存空间。
当进程访问虚拟内存中的数据时,操作系统会根据需求将数据从磁盘加载到内存中。
虚拟内存的实现依赖于操作系统中的内存管理单元(MMU)和页面置换算法。
当进程访问一个未加载到内存中的页时,MMU会触发缺页异常,操作系统需要根据页面置换算法来选择一些页将其从内存中换出,腾出空间来加载新的页。
常见的页面置换算法包括最佳置换算法(OPT)、先进先出置换算法(FIFO)、最近最久未使用置换算法(LRU)等。
操作系统实习二报告
实验二主存储器空间的分配和回收一、实验题目:模拟在分页式管理方式下采用位示图来表示主存分配情况,实现主存空间的分配和回收。
二、实验目的:主存的分配和回收的实现与主存储器的管理方式有关,通过本实习理解在不同的存储管理方式下应怎样实现主存空间的分配和回收。
三、实验内容:一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。
当用户提出申请存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。
当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。
四、程序中使用的数据结构及符号说明:五、程序流程图:六、程序源代码:#include <stdlib.h>#include <stdio.h>typedef int datatype;typedef struct node{datatype pageNum,blockNum;struct node *next;}linknode;typedef linknode *linklist;linklist creatlinklist(int n)/*尾插法创建带头结点的单链表*/{linklist head,r,s;int x,y,i=0;head=r=(linklist)malloc(sizeof(linknode));printf("\n请分别输入页表的页号及块号(-1表示空):\n");printf("\n页号| 块号\n");while (i<n){scanf("%d %d",&x,&y);s=(linklist)malloc(sizeof(linknode));s->pageNum=x;s->blockNum=y;r->next=s;r=s;i++;}r->next=NULL;return head;}void init(int g[100][100],int N)/*初始化位示图,将值全置为零,0表示空闲状态*/{int i,j;for(i=0;i<100;i++){for(j=0;j<100;j++){g[i][j]=0; //全置为零}}g[N+1][0]=N*N; //在数组最后一个数的后面设置一个空间用来存放剩余空闲块数}linklist Init(linklist head,int g[100][100],int n,int N){linklist p;int i,j;p=head->next;if(n<=g[N+1][0]) //首先判断作业的页数是否小于等于位示图剩余空闲块的个数{while(p){i=p->blockNum/N;j=p->blockNum%N;g[i][j]=1;g[N+1][0]--;p=p->next;}}return head;}printStr(int g[100][100],int N)/*打印位示图*/{int i,j;printf("\n此时位示图为:\n");printf("\n ");for(i=0;i<N;i++){printf(" ");printf("%d",i);}printf("\n");for(i=0;i<N;i++){printf("%d",i);for(j=0;j<N;j++){printf(" ");printf("%d",g[i][j]);}printf("\n");}printf("\n");}void print(linklist head)/*输出带头结点的单链表*/{linklist p;p=head->next;printf("\n该页表为:\n");printf("\n");printf("\n 页号| 块号\n");while(p){printf("%11d%7d\n",p->pageNum,p->blockNum);p=p->next;}printf("\n");}linklist Dis(linklist head,int g[100][100],int n,int N){linklist p;int i,j;p=head->next;if(n<=g[N+1][0]) //首先判断作业的页数是否小于等于位示图剩余空闲块的个数{while(p){for(i=0;i<N;i++){for(j=0;j<N;j++){if(g[i][j]==0){p->blockNum=N*i+j; //将对应块号记录到页表g[i][j]=1; //将块置1,表示已被占用g[N+1][0]--; //剩余空闲块减1break; //跳出循环,进行下一个页的分配}}break; //跳出循环}p=p->next; //下一个页进行分配}return head;}}linklist Recy(linklist head,int g[100][100],int n,int N)/*回收已经完成的页*/ {int i,j;linklist p;p=head->next;while(p&&p->pageNum!=n) //找出要回收的页号{p=p->next;}if(p) //找到{i=p->blockNum/N;j=p->blockNum%N;g[i][j]=0; //将该块置0,表空闲状态g[N+1][0]++;p->blockNum=-1; //页表中对应的块号为空,置成-1}return head;}void main(){int m,n,N;int x,y,a,b,t;int graph[100][100];linklist head,Head;printf("\n*****分页式存储管理分配及回收算法*****\n");printf("\n请输入位示图字长:");scanf("%d",&N);printf("\n请输入已占用内存作业的页数:");scanf("%d",&m);head=creatlinklist(m);init(graph,N);head=Init(head,graph,m,N);printStr(graph,N);printf("\n当前空闲块数为:%d",graph[N+1][0]);printf("\n\n现在进行作业分配:\n");printf("\n请输入需要分配的作业的页数:");scanf("%d",&n);Head=creatlinklist(n);Head=Dis(Head,graph,n,N);print(Head);printStr(graph,N);printf("\n当前空闲块数为:%d",graph[N+1][0]);printf("\n\n您是否想回收已完成的页,“是”请按1,“否”请按0:");scanf("%d",&x);if(x) //判断是否要回收{printf("\n请输入您要回收的页号:");scanf("%d %d %d %d",&y,&a,&b,&t);head=Recy(head,graph,y,N);head=Recy(head,graph,a,N);head=Recy(head,graph,b,N);head=Recy(head,graph,t,N);printStr(graph,N);}printf("\n当前空闲块数为:%d",graph[N+1][0]);printf("\n");}七、运行结果:实习小结:本次实验是自己花了很多的时间去琢磨去尝试才完成的,虽然还不是很完美,但是在设计的过程中自己在对编程方面的逻辑思维得到了很好的锻炼。
操作系统实验之处理机调度实验报告
操作系统实验之处理机调度实验报告一、实验目的处理机调度是操作系统中的核心功能之一,本次实验的主要目的是通过模拟不同的处理机调度算法,深入理解操作系统对处理机资源的分配和管理策略,比较不同调度算法的性能差异,并观察它们在不同负载情况下的表现。
二、实验环境本次实验使用的操作系统为 Windows 10,编程语言为 Python 38。
实验中使用了 Python 的相关库,如`numpy`、`matplotlib`等,用于数据生成、计算和图形绘制。
三、实验原理1、先来先服务(FCFS)调度算法先来先服务算法按照作业到达的先后顺序进行调度。
先到达的作业先被服务,直到完成或阻塞,然后再处理下一个到达的作业。
2、短作业优先(SJF)调度算法短作业优先算法选择预计运行时间最短的作业先执行。
这种算法可以有效地减少作业的平均等待时间,但可能导致长作业长时间等待。
3、时间片轮转(RR)调度算法时间片轮转算法将处理机的时间分成固定长度的时间片,每个作业轮流获得一个时间片的处理时间。
当时间片用完后,如果作业还未完成,则将其放入就绪队列的末尾等待下一轮调度。
4、优先级调度算法优先级调度算法为每个作业分配一个优先级,优先级高的作业先被执行。
优先级可以根据作业的性质、紧急程度等因素来确定。
四、实验内容与步骤1、数据生成首先,生成一组模拟的作业,包括作业的到达时间、预计运行时间和优先级等信息。
为了使实验结果更具代表性,生成了不同规模和特征的作业集合。
2、算法实现分别实现了先来先服务、短作业优先、时间片轮转和优先级调度这四种算法。
在实现过程中,严格按照算法的定义和规则进行处理机的分配和调度。
3、性能评估指标定义了以下性能评估指标来比较不同调度算法的效果:平均等待时间:作业在就绪队列中的等待时间的平均值。
平均周转时间:作业从到达系统到完成的时间间隔的平均值。
系统吞吐量:单位时间内完成的作业数量。
4、实验结果分析对每种调度算法进行多次实验,使用不同的作业集合,并记录相应的性能指标数据。
计算机操作系统:处理机调度模拟实验资料
课程实验报告
在单处理机的情况下模拟用优先权的时间片轮转调度策略实现处理机调度,以加深了解处理机调度的工作过程。
要求:
可利用先来先服务、短作业优先、响应比高者优先、多级反馈队列模型、时间片轮转法等,来实现处理机的调度。
根据单处理机,多任务的问题特性做好软件实现的需求分析。
可根据问题的实际需要,可选择进程数量。
当系统运行时,能直观地、动态地反映当前处理机状态及各进程执行的状况。
描述6.create函数用于创建队列
7.insert为插入函数,用于将一个时间片运行结束的进程插入到就绪进程的
队尾
8.priority函数:如果有进程就绪,就将处理机分配给该进程让他执行。
调试过程及实验结果
总结每次运行一步,电脑将会将该时刻所有进程控制块的运行状态显示给用户。
包括进程名、要求运行时间、已经运行时间、还需要运行时间、状态等信息。
当每个进程运行一个时间片之后将它从该队列中移除,添加到就绪队列队尾中以便使每个进程可以循环执行。
当要求运行时间和已运行时间相等时,说明该进程运行结束,将该进程撤出该队列并且不再添加到就绪队列中。
直到就绪队列中没有就绪进程为止
附录#define _CRT_SECURE_NO_DEPRECATE #include"stdio.h"
#include"stdlib.h"
#include"string.h"
typedef struct node
{
char pname[10]; //进程名
int rtime; //已运行时间
int sytime; //剩余时间。
操作系统实验-存储管理
操作系统实验-存储管理操作系统实验-存储管理1、引言1.1 概述在操作系统中,存储管理是一个关键的任务。
它负责将程序和数据加载到内存中,管理内存的分配和回收,并确保不同进程之间的内存互不干扰。
本实验旨在深入了解并实践存储管理的相关概念和算法。
1.2 目的本实验的目的是让学生通过实际操作,了解存储管理的基本原理和常用算法,包括分页、分段和虚拟内存等。
通过实验,学生将学会如何实现内存分配和回收,以及处理内存碎片等问题。
1.3 实验环境- 操作系统:Windows、Linux、MacOS等- 编程语言:C、C++等2、实验步骤2.1 实验准备- 安装相应的开发环境和工具- 创建一个空白的项目文件夹,用于存放实验代码和相关文件2.2 实验一、分页存储管理- 理解分页存储管理的概念和原理- 实现一个简单的分页存储管理系统- 设计测试用例,验证分页存储管理的正确性和有效性2.3 实验二、分段存储管理- 理解分段存储管理的概念和原理- 实现一个简单的分段存储管理系统- 设计测试用例,验证分段存储管理的正确性和有效性2.4 实验三、虚拟存储管理- 理解虚拟存储管理的概念和原理- 实现一个简单的虚拟存储管理系统- 设计测试用例,验证虚拟存储管理的正确性和有效性3、实验结果分析3.1 分页存储管理结果分析- 分析分页存储管理系统的性能优缺点- 比较不同页面大小对系统性能的影响3.2 分段存储管理结果分析- 分析分段存储管理系统的性能优缺点- 比较不同段大小对系统性能的影响3.3 虚拟存储管理结果分析- 分析虚拟存储管理系统的性能优缺点- 比较不同页面置换算法对系统性能的影响4、总结与展望4.1 实验总结- 总结本次实验的收获和体会- 分析实验中遇到的问题和解决方法4.2 实验展望- 探讨存储管理领域的未来发展方向- 提出对本实验的改进意见和建议附件:无法律名词及注释:- 存储管理:操作系统中负责管理内存的任务,包括内存分配、回收和管理等功能。
处理器调度实验报告
一、实验目的1. 理解处理器调度的基本概念和原理;2. 掌握常用的处理器调度算法,如先来先服务(FCFS)、短作业优先(SJF)、优先级调度等;3. 分析不同调度算法的性能指标,如平均周转时间、平均带权周转时间等;4. 通过实验,提高实际操作和编程能力。
二、实验原理处理器调度是操作系统中的一个重要组成部分,其主要任务是合理分配处理器资源,使系统中的多个进程高效、有序地运行。
常见的处理器调度算法有以下几种:1. 先来先服务(FCFS):按照进程到达就绪队列的顺序进行调度,先到先服务;2. 短作业优先(SJF):优先选择运行时间最短的进程执行;3. 优先级调度:根据进程的优先级进行调度,优先级高的进程先执行;4. 时间片轮转(RR):将每个进程分配一个时间片,按照时间片轮转的方式调度进程。
三、实验内容1. 实验环境:Windows操作系统,Python编程语言;2. 实验工具:Python编程环境,如PyCharm、Spyder等;3. 实验步骤:(1)设计一个进程类,包含进程名、到达时间、运行时间、优先级等属性;(2)编写调度算法,实现FCFS、SJF、优先级调度和时间片轮转算法;(3)模拟进程执行过程,记录各个进程的执行时间、等待时间、周转时间等性能指标;(4)分析不同调度算法的性能,比较其优劣。
四、实验结果与分析1. FCFS调度算法实验结果:平均周转时间为20,平均带权周转时间为1.25。
分析:FCFS调度算法简单易实现,但可能导致进程响应时间长,不利于实时性要求高的系统。
2. SJF调度算法实验结果:平均周转时间为16,平均带权周转时间为1.2。
分析:SJF调度算法可以缩短平均周转时间,提高系统性能,但可能使长作业长时间等待,影响公平性。
3. 优先级调度算法实验结果:平均周转时间为18,平均带权周转时间为1.3。
分析:优先级调度算法可以根据进程的优先级进行调度,提高系统响应速度,但可能导致低优先级进程长时间等待。
操作系统处理机调度实验报告word精品文档10页
处理机调度算法实验报告学号姓名时间专业班级实验题目:处理机调度算法一、实验目的在了解操作系统的基础上全面了解处理机调度算法的实现以及过程,详细了解处理机调度算法的机制,充分了解调度的过程及状态,采用优先数法进程调度算法来模拟演示进程调度二、实验内容与步骤:1. 了解进程的三种状态状态:ready、running、finish2.了解进程需要的CPU时间以时间片为单位确定3.编写一段程序#include <stdio.h>#include <stdlib.h>#define P_NUM 5#define P_TIME 50enum state{ready,execute,block,finish};struct pcbb{char name[4];int priority;int cputime;int needtime;int count;enum state process;struct pcbb *next;};typedef struct pcbb pcb;void display_menu(){printf("CHOOSE THE ALGORITHM:\n");printf("1 PRIORITY\n");printf("2 ROUNDROBIN\n");printf("3 EXIT\n");}pcb* get_process(){pcb *q;pcb *p;pcb *t;int i = 0;printf("input name and time\n");while (i < P_NUM){q=(pcb *)malloc(sizeof(pcb));scanf("%s",q->name);scanf("%d",&q->needtime);q->cputime = 0;q->priority = P_TIME - q->needtime;q->process = ready;q->next = NULL;if(i==0){p = q;t = q;}else{t->next = q;t = q;}i++;}return p;}void free_process(pcb *p){pcb *q;while(p!= NULL){q = p;p = p->next;free(q);}}void display(pcb *p){printf("name cputime needtime priority state\n");while(p){printf("%s",p->name);printf(" ");printf("%d",p->cputime);printf(" ");printf("%d",p->needtime);printf(" ");printf("%d",p->priority);printf(" ");switch(p->process){case ready:printf("ready\n");break;case execute:printf("execute\n"); break;case block:printf("block\n"); break;case finish:printf("finish\n"); break;}p = p->next;}}int process_finish(pcb *q){int b1 = 1;while(b1&&q){b1 = b1&&q->needtime==0;q = q->next;}return b1;}void cpuexe(pcb *q){pcb *t = q;int tp = 0;while(q){if (q->process!=finish){q->process = ready;if(q->needtime==0){q->process = finish;}}if(tp<q->priority&&q->process!=finish){tp = q->priority;t = q;}q = q->next;}if(t->needtime!=0){t->priority -=3;t->needtime --;t->process = execute;t->cputime++;}}void priority_cal(){pcb *p;p = get_process();int cpu = 0;while(!process_finish(p)){cpu++;printf("cputime:%d\n",cpu);cpuexe(p);display(p);sleep(2);}free_process(p);printf("All processes have finished\n"); }pcb *get_process_round(){pcb *q;pcb *p;pcb *t;int i = 0;printf("input name and time\n");while (i<P_NUM){q=(pcb *)malloc(sizeof(pcb));scanf("%s",q->name);scanf("%d",&q->needtime);q->cputime = 0;q->count = 0;q->process = ready;q->next = NULL;if(i==0){p = q;t = q;}else{t->next = q;t = q;}i++;}return p;}void cpu_round(pcb *q){if(q->needtime==1)q->cputime++;elseq->cputime +=2;q->needtime -=2;if(q->needtime<0){q->needtime = 0;}q->count++;q->process = execute;}pcb *get_next(pcb *k,pcb *head){pcb *t;t = k;do{t =t->next;}while ( t && t->process == finish);if(t == NULL){t = head;while(t->next!=k && t->process == finish){t = t->next; } }return t;}void set_state(pcb *p){while(p){if(p->needtime == 0){p->process = finish;}if(p->process == execute){p->process = ready; }p = p->next; }}void display_round(pcb *p){printf("name cputime needtime count state\n");while(p){printf("%s",p->name);printf(" ");printf("%d",p->cputime);printf(" ");printf("%d",p->needtime);printf(" ");printf("%d",p->count);printf(" ");switch(p->process){case ready:printf("ready\n");break;case execute:printf("execute\n"); break;case block:printf("block\n"); break;case finish:printf("finish\n"); break; }p = p->next; }}void round_cal(){pcb *p;pcb *r;p = get_process_round();int cpu = 0;r=p;while(!process_finish(p)){if(r->needtime==1)cpu+=1;elsecpu+=2;cpu_round(r);r = get_next(r,p);printf("cputime:%d\n",cpu);display_round(p);set_state(p);sleep(2);}free_process(p); }main(){display_menu();int k;scanf("%d",&k);switch(k){case 1:priority_cal();break;case 2:round_cal();break;case 3:break;default:printf("YOU HA VE NOT CHOOSE ANY ALGORITHM!\n");}}运行后结果如下:[root@rhel5hbzy ~]# gcc -o chuliji chuliji.c[root@rhel5hbzy ~]# ./mCHOOSE THE ALGORITHM:1 PRIORITY2 ROUNDROBIN3 EXIT1input name and timejing 2aaaa 8bbbb5ffff4ggg 6cputime:1name cputime needtime priority state jing- 1 1 45 execute aaaa* 0 8 42 ready bbbb2 0 0 50 finish ffff2 0 0 50 finish ggg 0 6 44 ready rtyucputime:2name cputime needtime priority state jing* 2 0 42 execute aaaa* 0 8 42 ready bbbb2 0 0 50 finish ffff2 0 0 50 finish ggg 0 6 44 ready 5cputime:3name cputime needtime priority state jing* 2 0 42 finish aaaa* 0 8 42 ready bbbb2 0 0 50 finish ffff2 0 0 50 finish ggg 1 5 41 execute 2cputime:4name cputime needtime priority state jing* 2 0 42 finish aaaa' 1 7 39 execute bbbb2 0 0 50 finish ffff2 0 0 50 finish ggg 1 5 41 readycputime:5name cputime needtime priority state jing* 2 0 42 finish aaaa' 1 7 39 ready bbbb2 0 0 50 finish ffff2 0 0 50 finish ggg 2 4 38 execute cputime:6name cputime needtime priority state jing* 2 0 42 finish aaaa$ 2 6 36 execute bbbb2 0 0 50 finish ffff2 0 0 50 finishggg 2 4 38 ready cputime:7name cputime needtime priority state jing* 2 0 42 finish aaaa$ 2 6 36 ready bbbb2 0 0 50 finish ffff2 0 0 50 finish ggg 3 3 35 execute cputime:8name cputime needtime priority state jing* 2 0 42 finish aaaa! 3 5 33 execute bbbb2 0 0 50 finish ffff2 0 0 50 finish ggg 3 3 35 ready cputime:9name cputime needtime priority state jing* 2 0 42 finish aaaa! 3 5 33 ready bbbb2 0 0 50 finish ffff2 0 0 50 finish ggg 4 2 32 execute cputime:10name cputime needtime priority state jing* 2 0 42 finish aaaa- 4 4 30 execute bbbb2 0 0 50 finish ffff2 0 0 50 finish ggg 4 2 32 ready cputime:11name cputime needtime priority state jing* 2 0 42 finish aaaa- 4 4 30 ready bbbb2 0 0 50 finish ffff2 0 0 50 finish ggg 5 1 29 execute cputime:12name cputime needtime priority state jing* 2 0 42 finish aaaa 5 3 27 execute bbbb2 0 0 50 finish ffff2 0 0 50 finish ggg 5 1 29 ready cputime:13name cputime needtime priority statejing* 2 0 42 finishaaaa 5 3 27 readybbbb2 0 0 50 finishffff2 0 0 50 finishggg 6 0 26 execute cputime:14name cputime needtime priority statejing* 2 0 42 finishaaaa 6 2 24 executebbbb2 0 0 50 finishffff2 0 0 50 finishggg 6 0 26 finish3cputime:15name cputime needtime priority statejing* 2 0 42 finishaaaa 7 1 21 executebbbb2 0 0 50 finishffff2 0 0 50 finishggg 6 0 26 finish cputime:16name cputime needtime priority statejing* 2 0 42 finishaaaa 8 0 18 executebbbb2 0 0 50 finishffff2 0 0 50 finishggg 6 0 26 finishAll processes have finished[root@rhel5hbzy ~]# rtyu2bash: rtyu2: command not found[root@rhel5hbzy ~]# 3bash: 3: command not found三、分析与体会多道程序设计中,通常是若干个进程同时处于就绪状态,必须依照某种策略来决定哪个进程优先占有处理机。
处理器调度实验报告
处理器调度实验报告处理器调度实验报告一、实验目的处理器调度是操作系统中的重要组成部分,它负责决定哪个进程优先执行,以及如何分配处理器资源。
本次实验旨在通过模拟不同的处理器调度算法,深入了解各种算法的工作原理和优缺点。
二、实验背景在多道程序设计环境下,多个进程同时竞争有限的处理器资源。
为了提高系统的吞吐量和响应速度,需要合理地调度进程,使得每个进程都能得到公平的执行机会。
处理器调度算法的选择直接影响到系统的性能和用户体验。
三、实验内容本次实验使用模拟器来模拟不同的处理器调度算法,包括先来先服务(FCFS)、最短作业优先(SJF)、时间片轮转(RR)和优先级调度(Priority Scheduling)。
通过对这些算法的模拟实验,我们可以观察到它们在不同场景下的表现。
四、实验过程与结果首先,我们设计了一组测试用例,每个测试用例包含若干个进程,每个进程具有不同的执行时间和优先级。
然后,我们分别使用不同的调度算法对这些进程进行调度,并记录下每个进程的等待时间和周转时间。
在FCFS算法下,进程按照到达的先后顺序依次执行。
这种算法简单直观,但是容易造成后面进程的等待时间过长,尤其是当某个进程执行时间较长时。
SJF算法根据进程的执行时间来进行调度,执行时间最短的进程先执行。
这种算法能够最大程度地减少平均等待时间,但是对于长作业来说,可能会出现饥饿现象。
RR算法将处理器的时间划分为若干个时间片,每个进程在一个时间片内执行一定的时间,然后切换到下一个进程。
这种算法能够保证每个进程都能得到执行的机会,但是对于执行时间较长的进程来说,可能会造成较大的上下文切换开销。
优先级调度算法根据进程的优先级来进行调度,优先级高的进程先执行。
这种算法可以根据不同的场景进行调整,但是可能会出现优先级反转的问题。
通过实验结果的分析,我们可以看到不同的调度算法在不同场景下的表现。
对于短作业来说,SJF算法能够最大程度地减少等待时间;对于长作业来说,RR算法能够保证公平性;而优先级调度算法则适用于一些需要特定优先级处理的场景。
《操作系统》实验二
《操作系统》实验二一、实验目的本实验旨在加深对操作系统基本概念和原理的理解,通过实际操作,提高对操作系统设计和实现的认知。
通过实验二,我们将重点掌握进程管理、线程调度、内存管理和文件系统的基本原理和实现方法。
二、实验内容1、进程管理a.实现进程创建、撤销、阻塞、唤醒等基本操作。
b.设计一个简单的进程调度算法,如轮转法或优先级调度法。
c.实现进程间的通信机制,如共享内存或消息队列。
2、线程调度a.实现线程的创建、撤销和调度。
b.实现一个简单的线程调度算法,如协同多任务(cooperative multitasking)。
3、内存管理a.设计一个简单的分页内存管理系统。
b.实现内存的分配和回收。
c.实现一个简单的内存保护机制。
4、文件系统a.设计一个简单的文件系统,包括文件的创建、读取、写入和删除。
b.实现文件的存储和检索。
c.实现文件的备份和恢复。
三、实验步骤1、进程管理a.首先,设计一个进程类,包含进程的基本属性(如进程ID、状态、优先级等)和操作方法(如创建、撤销、阻塞、唤醒等)。
b.然后,实现一个进程调度器,根据不同的调度算法对进程进行调度。
可以使用模拟的方法,不需要真实的硬件环境。
c.最后,实现进程间的通信机制,可以通过模拟共享内存或消息队列来实现。
2、线程调度a.首先,设计一个线程类,包含线程的基本属性(如线程ID、状态等)和操作方法(如创建、撤销等)。
b.然后,实现一个线程调度器,根据不同的调度算法对线程进行调度。
同样可以使用模拟的方法。
3、内存管理a.首先,设计一个内存页框类,包含页框的基本属性(如页框号、状态等)和操作方法(如分配、回收等)。
b.然后,实现一个内存管理器,根据不同的内存保护机制对内存进行保护。
可以使用模拟的方法。
4、文件系统a.首先,设计一个文件类,包含文件的基本属性(如文件名、大小等)和操作方法(如创建、读取、写入、删除等)。
b.然后,实现一个文件系统管理器,包括文件的存储和检索功能。
操作系统页面调度算法程序实验报告
操作系统页面调度算法程序实验报告一、实验背景操作系统是计算机系统中最重要的组成部分之一,它负责管理计算机的资源、协调各个程序的运行和提供用户与计算机之间的接口。
而页面调度算法则是操作系统中非常重要的一个部分,它主要用于管理内存中的页面,以提高计算机系统的性能和效率。
二、实验目的本次实验旨在通过编写一个页面调度算法程序,深入理解操作系统中页面调度算法的原理和实现方法,并掌握如何使用C语言进行程序设计和开发。
三、实验原理1. 页面调度算法概述在操作系统中,为了提高内存利用率和进程执行效率,通常会将进程所需的数据或指令分割成多个大小相等的块(即“页面”),并将这些页面存储到内存中。
当进程需要访问某个页面时,如果该页面已经在内存中,则直接访问即可;如果该页面不在内存中,则需要进行“缺页处理”,将其从磁盘读入内存,并将其中一个已经在内存中但未被访问过一段时间的页面替换出去。
而为了确定应该替换哪个页面,就需要使用一种称为“页面调度算法”的技术来进行决策。
常见的页面调度算法有FIFO、LRU、LFU等。
2. FIFO算法FIFO(First In First Out)算法是最简单的页面调度算法之一,它的原理是将最先进入内存的页面替换出去。
具体来说,当一个新页面需要进入内存时,如果内存已经满了,则将最先进入内存的页面替换出去,并将新页面插入到队列末尾。
3. LRU算法LRU(Least Recently Used)算法是一种比较常用的页面调度算法,它的原理是根据页面最近被访问的时间来进行决策。
具体来说,当一个新页面需要进入内存时,如果内存已经满了,则将最近访问时间最早且未被修改过的页面替换出去,并将新页面插入到队列末尾。
4. LFU算法LFU(Least Frequently Used)算法是一种根据页面使用频率来进行决策的调度算法。
具体来说,当一个新页面需要进入内存时,如果内存已经满了,则将使用频率最低的那个页面替换出去,并将新页面插入到队列末尾。
操作系统实验之处理机调度实验报告
1、开发工具
Clion for mac 2016,采用 cmake 编译。
2、主要源码
//先来先服务 void FCFS(List *p, int count) {
List temp; int i, j; //按照到达时间排序 for (i = 1; i < count; i++) {
min = 100; temp = p[k].Finish_time; for (j = 0; j < count; j++) {
if (p[j].order != 0 || temp - p[j].Arrival_time < 0) continue;
if (min > p[j].Service_time) {
max = 0;
temp = p[k].Finish_time; //找响应比最高任务 for (j = 0; j < count; j++) {
if (p[j].order != 0 || temp - p[j].Arrival_time <= 0) continue;
if (max < (temp - p[j].Arrival_time) / p[j].Service_time) {
if (temp > p[i].Arrival_time) {
temp = p[i].Arrival_time; k = i; } } //按照响应比大小设置优先级,以及相应参数 for (i = 0; i < count; i++) { p[k].order = ++flag; p[k].Start_time = temp; p[k].Wait_time = temp - p[k].Arrival_time; p[k].Finish_time = temp + p[k].Service_time; p[k].Turnover_time = p[k].Finish_time - p[k].Arrival_time; p[k].WeightedTurn_time = p[k].Turnover_time / p[k].Service_time;
操作系统内存管理实验指导书
实验二内存管理实验一、实验目的1.掌握基本的主存分配和回收算法,了解Windows 2000/XP的虚拟内存机制。
2.学习使用Windows 2000/XP的与内存相关的API函数。
3.掌握请求分页存储管理方式。
二、实验内容及要求1.实验内容使用Windows 2000/XP 的API 函数,创建两个线程,一个用于模拟内存的分配活动,一个用于跟踪并记录内存分配过程中的内存变化情况,要求这两个线程使用信号量进行同步。
每次内存分配按照相应的测试数据的要求进行操作。
每个测试数据单元描述一次内存分配操作,测试数据有程序随机自动产生,并把产生的测试数据保存在一个文件中。
模拟内存分配活动的线程可以从测试数据文件中读出要进行的内存操作。
每个内存操作包括以下内容:1)时间:操作等待时间,即等待相应时间后执行内存分配操作(要求随机产生);2)块数:操作的内存页数(要求随机产生);3)操作类型:可以是保留(reserve)、提交(commit)、释放(release)、回收(decommit)、加锁(lock)、解锁(unlock);保留:在虚拟地址空间分配,不分配物理空间提交:在物理地址空间分配回收:释放物理空间,但保留虚拟空间释放:释放物理空间和虚拟空间加锁:常驻内存,即防止操作系统把对应的内存空间换出到外存可以将这些操作编号,存放于文件中。
4)大小:指块的大小;5)访问权限:共五种PAGE_READONLY、PAGE_READWRITE、PAGE_EXCUTE、PAGE_EXECUTE_READ 和PAGE_ EXECUTE_READWRITE。
可以将这些权限编号,存放于文件中。
运行结果显示要求:每次内存分配操作给出一组此次分配的相关信息,包括操作类型、权限类型、分配的起始地址和大小等;每次内存分配操作之后给出一组关于系统和内存的当前状态的信息。
2.实验要求●学习并理解请求分页存储管理方式;●学习了解虚拟存储技术的技术特点;●熟悉实验环境,掌握相关API的使用方法;●设计程序,实现以页为单位的虚拟内存分配方法;●不限制所使用的程序设计语言;●查阅有关资料;●提交实验报告。
操作系统的进程调度与内存管理策略
操作系统的进程调度与内存管理策略在计算机系统中,操作系统扮演着至关重要的角色,负责管理和协调计算机中的各种资源。
其中,进程调度和内存管理是操作系统中两个关键的方面。
本文将探讨操作系统的进程调度和内存管理策略,以及它们对系统性能和效率的影响。
一、进程调度进程是操作系统中的执行实体,具有一定的程序、数据和执行状态。
在计算机系统中,可能有多个进程同时运行,操作系统需要合理地分配有限的CPU时间片给不同的进程,以确保系统的正常运行和资源利用的最大化。
1.1 先来先服务(FCFS)先来先服务是最简单的进程调度算法,按照进程到达的先后顺序进行调度。
当一个进程开始执行后,直到完成或者发生I/O请求才会释放CPU。
这种调度算法的优点是实现简单,公平性好,但容易产生"饥饿"现象,长作业会占据CPU时间,短作业需要等待时间较长。
1.2 短作业优先(SJF)短作业优先是一种基于作业执行时间的调度算法,优先选择估计执行时间最短的作业。
这种算法可以最大化CPU利用率,并且减少平均周转时间。
但是,由于无法准确估计作业的执行时间,可能会导致长作业等待时间过长。
1.3 时间片轮转(RR)时间片轮转算法将CPU时间分片,每个进程在一个时间片内执行完毕后,轮转到下一个进程执行。
这种调度算法能够保证每个进程都有机会获得CPU时间,避免了长作业等待时间过长的问题。
但是,如果时间片过长,会导致短作业等待时间增加;如果时间片过短,会导致更多的上下文切换开销。
二、内存管理策略内存管理是操作系统中的另一个重要方面,负责有效地分配和管理计算机系统中的内存资源。
主要有以下几种策略。
2.1 固定分区分配固定分区分配将系统内存分为若干固定大小的分区,每个分区只能装载一个进程。
这种策略简单直接,但是存在内存碎片问题,导致大量内存浪费。
2.2 动态分区分配动态分区分配将系统内存分为多个大小不同的动态分区,可以根据进程的实际需要进行分配。
深圳大学 操作系统 实验二 进程调度
for(i = 1; i<max; i++)
if(process[rpMax].rp<process[i].rp)
rpMax = i;
else if(process[rpMax].rp==process[i].rp&&process[rpMax].arriTime>process[i].arriTime)
实验三:实现CPU调度的高响应比优先算法,调度对象是进程,包含属性:名称、到达时间、运行时间等,对象属性根据不同算法可自行添加。算法分析:本题目不能够简单地把所有程序的运行时间进行排序,在每一轮先检查是否有程序到达且未执行,如果符合条件只有一个,就直接调度;如果有多个,计算程序的响应比,最大的程序获得调度。
hav++;
qWork[qhs[hav].arriTime;
process[hav].flag = true;
qWork[qhav].push(process[hav]);
}
else //不被抢占,完成p进程
{
now = now+p.serriTime;
while(!qWork.empty())
{
Process p = qWork.front();
if(p.serriTime<=(T+moreTime))
{
int n = getTime(p);
finishProcess[finish] = p;
finish++;
qWork.pop();
isNewProcess();
rpMax = i;
if(process[rpMax].flag == true) break;
操作系统实验二实验报告
实验二处理机管理(4学时)实验目的正确理解提高处理机的利用率及改善系统性能在很大程度上取决于处理机调度性能的好坏,在操作系统中调度的实质是一种资源分配,调度算法是指根据系统的资源分配策略规定的资源分配算法,对不同的系统和系统目标,应采用不的调度算法。
(或)在多道程序或多任务系统中,系统同时处于就绪状态的进程有若干个。
也就是说能运行的进程数远远大于处理机个数。
为了使系统中的各进程能有条不紊地运行,必须选择某种调度策略,以选择一进程占用处理机。
通过本实验,加深对处理机调度的理解。
实验内容处理机管理是操作系统中非常重要的部分。
为深入理解进程管理部分的功能,设计几个调度算法,模拟实现处理机的调度。
编程模拟FCFS调度算法、SJ(P)F算法、高优先权调度算法、基于时间片轮转调度算法。
注:“基于时间片轮转调度算法模拟”为必作,其余选做。
实验准备及实验设备计算机,Tc2.0实验步骤正确理解各调度算法的基本思想;根据各调度算法定义PCB(模拟)的格式:FCFS算法和基于时间片轮转调度算法,可设PCB的格式为:高优先权调度算法可设PC为:在正确理解各调度算的基础上编写出相应的程序。
在所设计的调度程序中,针对不同算法应包含显示和打印语句,以便显示或打印程序运行的初值和运行结果:各PCB的初始状态,选中运行进程的名称、运行后各PCB状态以及每次调度时,就绪队列的进程排列顺序(针对不同算法有所不同)。
(源程序)实验结果(运行所编的模拟调度程序,所得结果略)FCFS算法比较有利于长作业(进程),而不利于短作业(进程)。
SJ(P)F算法不利于长作业(进程),该算法未考虑作业的紧迫程序,因而不能保证紧迫性作业(进程)会被及时处理,并且由于作业(进程)的长短是用户所提供的估计执行时间而定的,致使该算法不一定能真正做到短作业优先调度。
高优先权(分动态和静态优先权)调度算法即照顾了短作业,又考虑了作业到达的紧迫性。
对于静态优先权法,系统开销小,但不够精确,可能出现优先权低的作业(进程)长期没有被调度的情况;对于动态优先权(高响应比优先)法,它既照顾了短作业,又考虑了作业的先后次序,不会使长作业长期得不到服务,但每要进行调度之前,都须做响应比的计算,会增加系统开销。
实验二:处理器调度
实验二:处理器调度一、实验内容选择一个调度算法,实现处理器调度。
二、实验目的在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。
当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。
本实验模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。
设计一个按优先数调度算法实现处理器调度的程序。
[提示]:(1) 假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为:其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。
指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“0”。
要求运行时间——假设进程需要运行的单位时间数。
优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。
状态——可假设有两种状态,“就绪”状态和“结束”状态。
五个进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。
(2) 在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。
(3) 为了调度方便,把五个进程按给定的优先数从大到小连成队列。
用一单元指出队首进程,用指针指出队列的连接情况。
例:队首标志K2K1 K2 K3 K4 K5PCB1 PCB2 PCB3 PCB4 PCB5(4) 处理器调度总是选队首进程运行。
采用动态改变优先数的办法,进程每运行一次优先数就减“1”。
由于本实验是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行:优先数-1要求运行时间-1来模拟进程的一次运行。
提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。
在这里省去了这些工作。
(5) 进程运行一次后,若要求运行时间 0,则再将它加入队列(按优先数大小插入,且置队首标志);若要求运行时间=0,则把它的状态修改成“结束”(E),且退出队列。
操作系统实验-CPU进程调度和内存分配_java版
操作系统实验第一期项目开发实现实验名称EXP.1 CPU SchedulingExp.2 Allocation & Reclaim实验内容一,选择一个调度算法,实现处理机调度;二,处理机调度过程中,主存储器空间的分配和回收;实验目的一,多道系统中,当就绪进程数大于处理机数时,须按照某种策略决定哪些进程优先占用处理机。
本实验模拟实现处理机调度,以加深了解处理机调度的工作;二,帮助了解在不同的存储管理方式下,应怎样实现主存空间的分配和回收;实验题目一,(1)设计一个按照优先权调度算法实现处理机调度的程序;(2)设计按时间片轮转实现处理机调度的程序;二,在可变分区管理方式下,采用最先适应算法实现主存空间的分配和回收;实验要求一,(a),PCB内容:进程名/PID;要求运行时间(单位时间);优先权;状态;PCB 指针;——(因课程内容原因,这个指针在设计中没用)1,可随机输入若干进程,并按优先权排序;2,从就绪队列首选进程运行:优先权-1/ 要求运行时间-1;要求运行时间=0时,撤销该进程;3,重新排序,进行下一轮调度;(b),最好采用图形界面;(c),可随时增加进程;(d),规定道数,设置后备队列和挂起状态。
若内存中进程数少于规定道数,可自动从后备队列调度一作业进入。
被挂起进程如=入挂起队列,设置解挂功能用于将指定挂起进程解挂入就绪队列;(e),每次调度后,显示各进程状态;二,(a),自行假设主存空间大小,预设操作系统所占大小并构造未分分区表;表目内容:起址、长度、状态(未分/空表目)(b),结合实验一,PCB增加为:{PID,要求运行时间,优先权,状态,所需内存大小,主存起始位置,PCB指针(失效)};(C)采用最先适应算法分配主存空间;(D),进程完成后,回收主存,并与相邻空闲分区合并;实验过程及分析1,初步设计:2,详细设计:(a),操作系统知识回顾:(1)作业进入内存中,由CPU分配产生PCB属性,并通过PCB记录进程状态,实验即以PCB代表进程模拟调度过程;(2)在多道系统中,多道系统中,当就绪进程数大于处理机数时,须按照某种策略决定哪些进程优先占用处理机,本实验采用优先级;(3),进程调度时,规定若就绪队列进程数少于6个,则自动从后备队列调入一个作业;(4),系统会将占有较多资源、预期结果不符合要求的进程自动挂起,并回收所占资源,而本实验设置为手动挂起;(5),在适宜条件下,系统会将挂起的进程自动解挂,而且只解挂到就绪队列;本实验为简化操作,设置为手动解挂,若解挂条件合适(即CPU各种资源可用),则解挂到就绪队列,并分配内存;若解挂条件不适宜,则解挂至后备队列,但不分配内存(实际上这是不对的,因为作业进入内存,由CPU标记PCB后,不能撤销PCB再返回内存,除非该进程执行结束,但本程序为体现解挂的意思,还是错误地设计为可以解挂到后备队列,读者需注意,这个功能可以在代码中注销,另外也希望有高手可以改进);(b),实验程序设计:(1),本实验采用java语言编程,并实现GUI界面显示;(2),为体现java语言面对对象程序设计的特点,实验设计为ProcessPCB、MemoryItem类封装PCB和所分配的内存各自的属性与方法;用ProcessRecords、MemoryRecords类封装数组方法;用SingleCPUScheduling实现GUI界面显示;(3),ProcessPCB类中,定义PCB的进程名、要求运行时间、优先级、状态、主存起始位置、所需内存大小这6个属性,并定义各属性的get和set方法,定义equals 方法用于对比类的属性,定义toString方法得到类属性的字符串,定义run方法封装优先权-1/ 要求运行时间-1的过程;MemoryItem类中,定义可分分区表每一可分记录的主存起始位置、内存大小及其get和set方法,定义toString方法得到可在界面显示的字符串;(4),ProcessRecords封装PCB数组的添加元素addItem和删除元素removeItem 方法,并构造函数getItem通过参数ProcessPCB和String查找数组元素,定义getNumberOfItems取数组大小,定义getItemsPriorities方法取所有数组元素的toString方法用于界面显示,定义iterator方法取得数组的迭代器;MemoryItem类中,定义Memory的内存起始位置和所需内存大小、、、、、、(5),MemoryRecords用同样的设计思想封装以MemoryItem为数组元素的各属性和方法;(6)SingleCPUScheduling类继承JFrame类,实现界面化显示;与上面相对应,实例化ProcessRecords(3次)和MemoryRecords(1次)作为私有变量,分别作为后备队列、就绪队列、挂起队列和内存可分分区表;在界面设计中,设计后备队列、挂起队列(附带解挂umount按钮)、就绪队列(附带挂起suspend按钮)可分分区表列表显示框,设置PCB添加框,附带添加至后备队列(addToBackup)、添加至就绪队列(addToReady)按钮,以及CPU当前执行状态显示框、系统日志显示框,和开始调度(systemStart)按钮,优先级和时间片单选按钮,以及时间片显示标签和文本编辑框;(7)界面设计详解;后备队列显示框用于显示已添加至后备队列的ProcessRecords 属性信息,其中主存起始位置默认为-1,表示未分配;挂起队列显示框用于显示从就绪队列挂起的PCB,其中属性“主存起始位置”(MemoryBase)将由非负数变为-1,表示挂起后收回内存;就绪队列显示框中显示就绪队列属性,其中“主存起始位置”均为非负,表示一分配内存;PCB信息添加框分列PCB6个属性显示标签和可编辑文本框,和添加按钮,用于添加PCB;系统日志显示框附属时间片显示标签和可编辑文本编辑框,可由用户决定时间片大小;对于实验一,界面如下:以上由SingleCPUScheduling001.java(另需ProcessPCB.java和PCBRdecords.java)(8)附属功能添加完善;最重要的是为程序添加线程,使程序能以停顿一段时间的频率自动运行;后备队列、挂起队列添加total显示标签和不可编辑文本显示框,用于显示各自数组中元素数目,挂起队列附属删除(remove)按钮,可删除挂起队列中的元素;后备、挂起、就绪队列均添加监听器,用于响应用户单击操作,可以在PCB信息添加框显示用户单击的那一条PCB的信息;PCB信息添加框附属reset按钮,用于一键清空信息框中信息,方便输入;系统日志面板附属系统暂停(systemPause)和系统重置(systemReset)按钮,分别用于暂停运行(方便用户观察当前运行结果)和重置系统(方便用户重复使用程序,免去关闭后重启本程序的麻烦);最终界面如图:实验结果报告级分析1,程序完成了实验所有的基本要求;2,本程序还存在一些技术上的问题,使得程序不能尽善尽美;如,PCB信息添加框没有“随机置入就绪队列”功能,添加PCB信息仍显得繁琐;就绪队列的挂起功能在程序自动运行时,存在反应异常(反应延迟或直接无反映);可分分区表只显示了当前可分的内存,没有显示已分的PCB及其对应内存使用情况,且没有利用图形和丰富的颜色来更好的展示;时间片设计还需要改进,使用效率不高;系统重置功能存在响应延迟的问题;另外,界面不够美观;还需要不断改进;实验感想通过这次实验,我对操作系统的进程调度和内存分配管理有了更加深入的了解,对操作系统内部的工作原理有了进一步的认识;通过编程,也巩固了我的程序设计和代码编写的能力,实验过程中遇到的各种问题以及解决问题的过程与方法,都是我获益匪浅;同时,程序的不完善,也将促使我在课程之后,继续学习、理解课程内容,并尽一切努力不断完善程序,做到尽善尽美;程序代码完整版(初学java,菜鸟级别,当然是将所学的全部照办照抄,实为臃肿,可为初学者引以为戒,注意代码质量!)这里谨贴出十分臃肿的代码,仅供初学者交流经验,重在开发的思想,了解开发的流程,而01版(精简版)代码在后面;ProcessPCB.javapackage src;public class ProcessPCB {// backupBAK 后备 ready 就绪 suspend 挂起 memory内存private String PID;private int RequiredTime;// private String Priority;private int Priority;private String Status;private int MwmoryBase = 0000;private int MemoryLimit;// private String PCBPointer;public ProcessPCB(String initpID, int initRTime, int initpriority, String status, int initBase, int initLimit) {this.PID = initpID;this.RequiredTime = initRTime;this.Priority = initpriority;this.Status = status;this.MwmoryBase = initBase;this.MemoryLimit = initLimit;}public String getPID() {if(this.PID == null)return " ";elsereturn this.PID;}public void setPID(String pid) {if(pid == null)this.PID = " ";elsethis.PID = pid;}public int getRequiredTime() {return this.RequiredTime;}public void setRequiredTime(int time) {this.RequiredTime = time;}public int getPriority() {return this.Priority;}public void setPriority(int priority) {this.Priority = priority;}public String getStatus() {if(this.Status == null)return" ";elsereturn this.Status;}public void setStatues(String statues) {if(statues == null)this.Status = " ";elsethis.Status = statues;}public int getMemoryBase() {return this.MwmoryBase;}public void setMemoryBase(int base) {this.MwmoryBase = base;}public int getMemoryLimit() {return this.MemoryLimit;}public void setMemoryLimit(int limit) {this.MemoryLimit = limit;}public boolean equals(ProcessPCB pcb) {if(pcb.getPID() == this.getPID()) {return true;}else return false;}public String toString() {return this.getPID() + "_" + this.getRequiredTime() + "_" + this.getPriority() + "_"+ this.getStatus() + "_" + this.getMemoryBase() + "_" + this.getMemoryLimit() + "\n";public void run() {this.RequiredTime = this.RequiredTime-1;this.Priority = this.Priority-1;}}MemoryItem.javapackage src;public class MemoryItem {private int memoryBase=0;private int memoryLimit=0;private int availableStatus=0;public MemoryItem(int initMemoryBase, int initMemoryLimit) { this.memoryBase = initMemoryBase;this.memoryLimit = initMemoryLimit;}public int getMemoryBase() {return this.memoryBase;}public void setMemoryBase(int base) {this.memoryBase = base;}public int getMemoryLimit() {return this.memoryLimit;}public void setMemoryLimit(int limit) {this.memoryLimit = limit;}public int getStatus() {return this.availableStatus;}public void setStatus(int status) {this.memoryBase = status;}public String toString() {return this.getMemoryBase() + "_" + this.getMemoryLimit() + "\n";}}PCBRecords.javapackage src;import java.util.ArrayList;import java.util.Iterator;public class PCBRecords implements Iterable<ProcessPCB> { private ArrayList<ProcessPCB> PCBItems;public ArrayList<ProcessPCB> getPCBItems() {return this.PCBItems;}public PCBRecords() {this.PCBItems = new ArrayList<ProcessPCB>();}public void addItem(ProcessPCB PcbItem) {this.PCBItems.add(PcbItem);}public void removeItem(ProcessPCB PCbItem) {this.PCBItems.remove(PCbItem);}public ProcessPCB getItem(ProcessPCB processPCB) {for (ProcessPCB pCbItem : this.PCBItems) {if (pCbItem.equals(processPCB)) {return pCbItem;}}return null;}public ProcessPCB getItem(String pid) {for (ProcessPCB pcBItem : this.PCBItems) {if (pcBItem.getPID().equals(pid)) {return pcBItem;}}return null;}public int getNumberOfItems() {return this.PCBItems.size();}public String[] getItemsProperties() {String itemsProperties[] = new String[getNumberOfItems()];int i = 0;for(Iterator iterator1 = PCBItems.iterator(); iterator1.hasNext();){ProcessPCB stu_Item = (ProcessPCB)iterator1.next();itemsProperties[i++] = stu_Item.toString();}return itemsProperties;}public Iterator<ProcessPCB> iterator() {return this.PCBItems.iterator();}}MemoryRecords.javapackage src;import java.util.ArrayList;import java.util.Iterator;public class MemoryRecords implements Iterable<MemoryItem> { private ArrayList<MemoryItem> memoryItems;public Iterator<MemoryItem> iterator() {// TODO Auto-generated method stubreturn this.memoryItems.iterator();}public ArrayList<MemoryItem> getMemoryItems() { return this.memoryItems;}public MemoryRecords() {this.memoryItems = new ArrayList<MemoryItem>();}public void addItem(MemoryItem newMemoryItem) { this.memoryItems.add(newMemoryItem);}public void removeItem(MemoryItem momoryItem) { this.memoryItems.remove(momoryItem);}public MemoryItem getMomoryItem(MemoryItem item) { for(MemoryItem mItem : this.memoryItems) {if(mItem.equals(item)) {return mItem;}}return null;}public MemoryItem getMemoryItem(int base) {for(MemoryItem mItem : this.memoryItems) {if(mItem.getMemoryBase() == base) {return mItem;}}return null;}public int getNumberOfItems() {return this.memoryItems.size();}public String[] getItemsProperties() {String itemsProperties[] = new String[getNumberOfItems()];int i=0;for(Iterator iterator1 = this.memoryItems.iterator(); iterator1.hasNext(); ) {MemoryItem mmItem = (MemoryItem) iterator1.next();itemsProperties[i++] = mmItem.toString();//????}//System.out.println(itemsProperties + "\n");if(itemsProperties == null) {itemsProperties[0] = " ";}return itemsProperties;}}SingleCPUSchedulingGUI001.Javaimport java.util.*;import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;import src.SingleCPUSchedulingGUI001.AddToBAKListener;import src.SingleCPUSchedulingGUI001.AddToReadyListener;import src.SingleCPUSchedulingGUI001.RemoveListener;import src.SingleCPUSchedulingGUI001.ResetListener;import src.SingleCPUSchedulingGUI001.ResetSystemListener;import src.SingleCPUSchedulingGUI001.StartSystemListener;import src.SingleCPUSchedulingGUI001.SuspendListener;import src.SingleCPUSchedulingGUI001.SystemPauseListener;import src.SingleCPUSchedulingGUI001.UmountListener;import src.SingleCPUSchedulingGUI001.priotiryListener;import src.SingleCPUSchedulingGUI001.timeslicListener;import java.io.*;import java.text.*;public class SingleCPUSchedulingGUI001 extends JFrame {private int systemStatues; //注意static 属性/*define 0--system prepare status--system reset and re-prepare 1--system start 2--system pause 3--system stop*//* Standar error stream */static private PrintWriter stdErr = new PrintWriter(System.err, true);static private int WIDTH = 600, HEIGHT = 700; // the size of the Frame 主面板/* 各列表对应的面板规格*//* 对应各名词释义backupBAK 后备ready 就绪suspend 挂起memory内存*/ static private int BackupBAK_CELL_SIZE = 250, BackupBAK_LIST_ROWS = 10; //后备队列static private int Suspend_CELL_SIZE = 250, Suspend_LIST_ROWS = 10; //挂起队列static private int Ready_CELL_SIZE = 200, Ready_LIST_ROWS = 6; //就绪队列static private int CPU_ROWS = 10, CPU_COLS = 22; //CPU面板static private int STATUS_ROWS = 8, STATUS_COLS = 30; //系统状态面板private int timeslice = 1; //设置时间片大小private int systemStatus=0; //设置系统状态0——系统预备状态,等待开始,1——系统运行状态,2——系统暂停状态static private int TOTAL__TEXTFIELD_SIZE = 10; // Size total text field 记录各队列元素个数private JList backupList, suspendList, readyList; //各队列相对应的数组列表// 进程添加框中的"添加至后备队列","添加至就绪队列","重置"Buttonprivate JButton addToBAKButton, addToReadyButton, resetButton;//就绪队列框中的"挂起",挂起队列框中的"解挂","删除"Buttonprivate JButton suspendButton, umountButton, removeButton;//Status面板中的"启动系统","重置系统"Buttonprivate JButton startButton, pauseButton, resetSyatemButton;//优先级和时间片单选钮及时间片显示框private JRadioButton priorityJRB, timesliceJRB;private JLabel timesliceSizeLabel;private JTextField timesliceJtf;//后备面板、进程添加面板、挂起面板、内存面板private JPanel backupBAKPanel, PCBItemPanel, suspendedPanel;//后备队列、挂起队列元素总数标签private JLabel backupTotalLabel, suspendTotalLabel;//进程信息标签进程编号PID,所需运行时间requiredTime,优先级priority,当前状态statues,内存中的基址base,所需内存大小limitprivate JLabel PIDLabel, requiredTimeLabel, priorityLabel, statuesLabel;//后备队列、挂起队列元素总数文本框(不可编辑)private JTextField backupTotalTextField, suspendTotalTextField;//进程信息文本框PID(可编辑),requiredTime(可编辑),priority(可编辑),status(不可编辑),base(不可编辑),limit(可编辑)private JTextField PIDTextField, requiredTimeTextField, priorityTextField, statusTextField;//CPU状态显示文本域(不可编辑),status信息文本域(用于现实程序每一步的操作和影响,不可编辑)private JTextArea CPUTextArea, statuesTextArea;//后备队列PCB数组,就绪、挂起,——内存(可分分区表)PCBRecords backupPCB, readyPCB, suspendedPCB;public static void main(String[] args) throws IOException {// TODO Auto-generated method stubnew SingleCPUSchedulingGUI001().initFrame();}public void initFrame() {backupList = new JList();backupList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);backupList.setVisibleRowCount(BackupBAK_LIST_ROWS);backupList.setFixedCellWidth(BackupBAK_CELL_SIZE);suspendList = new JList();suspendList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);suspendList.setVisibleRowCount(Suspend_LIST_ROWS);suspendList.setFixedCellWidth(Suspend_CELL_SIZE);readyList = new JList();readyList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);readyList.setVisibleRowCount(Ready_LIST_ROWS);readyList.setFixedCellWidth(Ready_CELL_SIZE);suspendButton = new JButton("Suspend");addToBAKButton = new JButton("AddToBAK");addToReadyButton = new JButton("AddToReady");resetButton = new JButton("Reset");umountButton = new JButton("Umount");removeButton = new JButton("Remove");startButton = new JButton("StartSchuliding");pauseButton = new JButton("Pause");resetSyatemButton = new JButton("ResetSystem");priorityJRB = new JRadioButton("Priority", true);timesliceJRB = new JRadioButton("Timeslice");backupTotalLabel = new JLabel("Total:");backupTotalTextField = new JTextField("0", TOTAL__TEXTFIELD_SIZE);backupTotalTextField.setEditable(false);suspendTotalLabel = new JLabel("Total:");suspendTotalTextField = new JTextField("0", TOTAL__TEXTFIELD_SIZE);suspendTotalTextField.setEditable(false);timesliceSizeLabel = new JLabel("Timeslice");timesliceJtf = new JTextField("3", 5);timesliceJtf.setEditable(true);CPUTextArea = new JTextArea(CPU_ROWS, CPU_COLS);CPUTextArea.setEditable(false);statuesTextArea = new JTextArea(STATUS_ROWS, STATUS_COLS);statuesTextArea.setEditable(false);/* north panel*/// JPanel northPanel = new JPanel(new BorderLayout());JPanel northPanel = new JPanel(new GridLayout(1, 3));// JPanel north = new JPanel(new BorderLayout());// ProcessPCB item information PanelPCBItemPanel = new JPanel(new BorderLayout());PCBItemPanel.setBorder(BorderFactory.createTitledBorder("PCBItem Information"));JPanel PCBItemButtonJPanel = new JPanel(new GridLayout(3, 1));PCBItemButtonJPanel.add(addToBAKButton);PCBItemButtonJPanel.add(addToReadyButton);PCBItemButtonJPanel.add(resetButton);PCBItemPanel.add(this.initPCBItemPanel(), BorderLayout.CENTER);PCBItemPanel.add(PCBItemButtonJPanel, BorderLayout.SOUTH);//backupBAKList PanelbackupBAKPanel = new JPanel(new BorderLayout());backupBAKPanel.setBorder(BorderFactory.createTitledBorder("BackupList"));JPanel backupTotalPAnel = new JPanel();backupTotalPAnel.add(backupTotalLabel);backupTotalPAnel.add(backupTotalTextField);backupBAKPanel.add (new JScrollPane(backupList,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER);backupBAKPanel.add(backupTotalPAnel, BorderLayout.SOUTH);// north.add(backupBAKPanel, BorderLayout.WEST);// north.add(PCBItemPanel, BorderLayout.CENTER);// SuspendList PanelsuspendedPanel = new JPanel(new BorderLayout());suspendedPanel.setBorder(BorderFactory.createTitledBorder("SuspendList"));JPanel suspendedTotalPAnel = new JPanel();suspendedTotalPAnel.add(suspendTotalLabel);suspendedTotalPAnel.add(suspendTotalTextField);JPanel suspendComponentPanel = new JPanel(new GridLayout(1, 2));suspendComponentPanel.add(umountButton);suspendComponentPanel.add(removeButton);suspendedPanel.add (suspendedTotalPAnel, BorderLayout.NORTH);suspendedPanel.add (new JScrollPane(suspendList,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED), BorderLayout.CENTER);suspendedPanel.add(suspendComponentPanel, BorderLayout.SOUTH);// northPanel.add(north, BorderLayout.CENTER);// northPanel.add(suspendedPanel, BorderLayout.EAST);northPanel.add(backupBAKPanel);northPanel.add(PCBItemPanel);northPanel.add(suspendedPanel);/* center Panel*/JPanel centrelPanel = new JPanel(new BorderLayout());// JPanel centrelPanel = new JPanel(new GridLayout(1, 3));// readyList panelJPanel readyListPanel = new JPanel(new BorderLayout());readyListPanel.setBorder(BorderFactory.createTitledBorder("ReadyList"));readyListPanel.add (new JScrollPane(readyList,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));//, BorderLayout.CENTERreadyListPanel.add (suspendButton, BorderLayout.SOUTH);// CPU panelJPanel CPUPanel = new JPanel();CPUPanel.setBorder(BorderFactory.createTitledBorder("CPU"));CPUPanel.add (new JScrollPane(CPUTextArea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED));centrelPanel.add(readyListPanel, BorderLayout.WEST);centrelPanel.add(CPUPanel, BorderLayout.CENTER);/*statues panel*/JPanel southPanel = new JPanel(new BorderLayout());JPanel statuesPanel = new JPanel();statuesPanel.setBorder(BorderFactory.createTitledBorder("Statues"));statuesPanel.add (new JScrollPane(statuesTextArea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED)); //, BorderLayout.CENTER //statuesPanel.setSize(400, 100);//statuesPanel.setPreferredSize(new Dimension(400, 10));JPanel systemContralButtonPanel = new JPanel(new GridLayout(6, 1));systemContralButtonPanel.setBorder(BorderFactory.createTitledBorder("systemContral"));ButtonGroup group = new ButtonGroup();group.add(priorityJRB);group.add(timesliceJRB);JPanel porityPanel = new JPanel(new GridLayout(1, 2));porityPanel.add(timesliceSizeLabel);porityPanel.add(timesliceJtf);systemContralButtonPanel.add(priorityJRB);systemContralButtonPanel.add(timesliceJRB);systemContralButtonPanel.add(porityPanel);systemContralButtonPanel.add(startButton);systemContralButtonPanel.add(pauseButton);systemContralButtonPanel.add(resetSyatemButton);southPanel.add(statuesPanel, BorderLayout.CENTER);southPanel.add(systemContralButtonPanel, BorderLayout.EAST);// arrange panels in windowsetLayout(new BorderLayout());add(northPanel, BorderLayout.NORTH);add(centrelPanel, BorderLayout.CENTER);add(southPanel, BorderLayout.SOUTH); //statuesPanel// start listening for list and buttons eventsaddToBAKButton.addActionListener(new AddToBAKListener());addToReadyButton.addActionListener(new AddToReadyListener());resetButton.addActionListener(new ResetListener());suspendButton.addActionListener(new SuspendListener());umountButton.addActionListener(new UmountListener());removeButton.addActionListener(new RemoveListener());startButton.addActionListener(new StartSystemListener());pauseButton.addActionListener(new SystemPauseListener());resetSyatemButton.addActionListener(new ResetSystemListener());priorityJRB.addActionListener(new priotiryListener());timesliceJRB.addActionListener(new timeslicListener());backupPCB = new PCBRecords();readyPCB = new PCBRecords();suspendedPCB = new PCBRecords();backupList.setListData(backupPCB.getItemsProperties());readyList.setListData(readyPCB.getItemsProperties());suspendList.setListData(suspendedPCB.getItemsProperties());this.setTitle("CPUSchudling");this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setSize(WIDTH, HEIGHT);this.setResizable(true);this.setVisible(true);this.setLocation(200, 10);}public JPanel initPCBItemPanel() {JPanel iniPCBItemJPanel = new JPanel(new BorderLayout());JPanel iniNamePanel = new JPanel(new GridLayout(4, 1));JPanel iniValuePanel = new JPanel(new GridLayout(4, 1));PIDLabel = new JLabel("PID:");requiredTimeLabel = new JLabel("RequiredTime:");priorityLabel = new JLabel("Priority:");statuesLabel = new JLabel("Statues:");iniNamePanel.add(PIDLabel);iniNamePanel.add(requiredTimeLabel);iniNamePanel.add(priorityLabel);iniNamePanel.add(statuesLabel);PIDTextField = new JTextField("", 10);PIDTextField.setEditable(true);requiredTimeTextField = new JTextField("", 10);requiredTimeTextField.setEditable(true);priorityTextField = new JTextField("", 10);priorityTextField.setEditable(true);statusTextField = new JTextField("", 10);statusTextField.setEditable(false);iniValuePanel.add(PIDTextField);iniValuePanel.add(requiredTimeTextField);iniValuePanel.add(priorityTextField);iniValuePanel.add(statusTextField);iniPCBItemJPanel.add(iniNamePanel, BorderLayout.WEST);iniPCBItemJPanel.add(iniValuePanel, BorderLayout.CENTER);return iniPCBItemJPanel;}public int readInteger(String s) {int num = -1;try {num = Integer.parseInt(s);} catch(NumberFormatException numberformatexception) {statuesTextArea.append("Please input a positive integer!\n");num = -999;}return num;}public void addToBackupList(String newID, int s1, int s2, String s) {ProcessPCB item = backupPCB.getItem(newID);if(item != null) {statuesTextArea.append("The PCB " + newID + " has existed in Backup List!\n"+ "you need to modify the PID of the selected PCB!\n");while(item != null) {newID = s + newID;item = backupPCB.getItem(newID);}}ProcessPCB newPCB = new ProcessPCB(newID, s1, s2, "Waiting");backupPCB.addItem(newPCB);backupList.setListData(backupPCB.getItemsProperties());backupTotalTextField.setText(Integer.toString(backupPCB.getNumberOfItems()));}public void addToReadyList(String nowID, int s1, int s2, String s) {ProcessPCB item = readyPCB.getItem(nowID);if(item != null) {statuesTextArea.append("The PCB " + nowID + " has existed in Ready List!\n"+ "you need to modify the PID of the selected PCB!\n");while(item != null) {nowID = s + nowID;item = backupPCB.getItem(nowID);}}ProcessPCB newPCB = new ProcessPCB(nowID, s1, s2, "Ready");readyPCB.addItem(newPCB);sortReadyPCB();readyList.setListData(readyPCB.getItemsProperties());}class AddToBAKListener implements ActionListener {public void actionPerformed(ActionEvent event) {String newID = PIDTextField.getText();String newTime = requiredTimeTextField.getText();String newPriority = priorityTextField.getText();int s1 = 0, s2 = 0, tag1=-1, tag2=-1;if(newTime != null){s1 = readInteger(newTime);if(s1 > 0.0) tag1 = 1;else statuesTextArea.append("The neededTime must be a positive integer.\n");}if(newPriority != null){s2 = readInteger(newPriority);if(s1 != -999) tag2 = 1;else statuesTextArea.append("The priority must be an integer.\n");}if(tag1 ==1 && tag2 == 1 ) {if(newID == null) {statuesTextArea.append("The value of ID mustn't be null!\n");} else {addToBackupList(newID, s1, s2, "B");statuesTextArea.append("The PCB record item has been added to BackupList!\n");reset();}}}}class AddToReadyListener implements ActionListener {public void actionPerformed(ActionEvent event) {String nowID = PIDTextField.getText();String time = requiredTimeTextField.getText();String priority = priorityTextField.getText();int s1 = 0, s2 = 0;int tag1 = -1, tag2 = -1;if(time != null){s1 = readInteger(time);if(s1 > 0.0) tag1=1;else statuesTextArea.append("The neededTime must be a positive integer.\n");}if(priority != null){s2 = readInteger(priority);if(s2 != -999) tag2=1;else statuesTextArea.append("The priority must be an integer.\n");}if(tag1 ==1 && tag2 == 1) {if(nowID == null) {statuesTextArea.append("The value of ID mustn't be null!\n");} else {if(readyPCB.getNumberOfItems() < 6) {addToReadyList(nowID, s1, s2, "R");statuesTextArea.append("The student record item has been added to ReadyList!\n");} else {statuesTextArea.append("The ReadyList was full! The new ProcessPCB will be added to BackupList!\n");addToBackupList(nowID, s1, s2, "b");statuesTextArea.append("The student record item has been added to BackupList!\n");}reset();}}}}public void reset() {PIDTextField.setText("");requiredTimeTextField.setText("");priorityTextField.setText("");statusTextField.setText("");}/*** This inner class processes <code>resetButton</code> events.*/class ResetListener implements ActionListener {public void actionPerformed(ActionEvent event) {reset();}}/*** This inner class processes <code>suspendButton</code> events.*///注:在挂起时,不会触发进程调度,而是在点击"startSyatemJButton"时才会出发进程调度class SuspendListener implements ActionListener {/*** Removes an order item from the current order.** @param event the event object.*/public void actionPerformed(ActionEvent event) {String selectedReadyItem = null;String pid = "";if(readyPCB.getNumberOfItems() == 0){statuesTextArea.append("The readyList is empty!\n");} else {selectedReadyItem = (String) readyList.getSelectedValue();if(selectedReadyItem == null) {statuesTextArea.append("Please select an item from the ready list!\n");} else{StringTokenizer stringtokenizer = new StringTokenizer(selectedReadyItem, "_");pid = stringtokenizer.nextToken();ProcessPCB selectedItem = readyPCB.getItem(pid);if(selectedItem == null) {statuesTextArea.append("No student recorditem of Num " + pid + " is founded!\n");} else {ProcessPCB boolTtem = suspendedPCB.getItem(pid);if(boolTtem != null) {statuesTextArea.append("The PCB " + pid + " has existed in Suspend List!\n"+ "you need to modify the PID of the selected PCB!\n");while(boolTtem != null) {pid = "X" + pid;boolTtem = suspendedPCB.getItem(pid);}}ProcessPCB newPcb = new ProcessPCB(pid, selectedItem.getRequiredTime(),selectedItem.getPriority(),"Suspended");suspendedPCB.addItem(newPcb);readyPCB.removeItem(selectedItem);sortReadyPCB(); //注意考虑一下suspendList.setListData(suspendedPCB.getItemsProperties());readyList.setListData(readyPCB.getItemsProperties());statuesTextArea.append("The product has been suspended!\n"); suspendTotalTextField.setText(Integer.toString(suspendedPCB.getNumberOfItems()));}}}}}public void sortReadyPCB() {PCBRecords currentReadyPCB = new PCBRecords();int num = readyPCB.getNumberOfItems();if(num > 0) {for(int i=num; i>=1; i--) {Iterator readyIterator = readyPCB.iterator();ProcessPCB currentItem = (ProcessPCB) readyIterator.next();for( ; readyIterator.hasNext(); ) {ProcessPCB nowItem = (ProcessPCB) readyIterator.next();if(currentItem.getPriority() < nowItem.getPriority()) {currentItem = null;。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
<< "***************************" << endl ;
return -1 ;
}
void PCB::printPageTable()
{
outfile.open("PageTable.txt", ios_base::app) ;
outfile << "***************************"
<< " PCB p" << number << " "
代码:
#include<iostream>
#include<list>
#include<queue>
#include<iterator>
#include<windows.h>
#include<fstream>
#include<cstdlib>
#include<ctime>
using namespace std ;
第二点缺陷是,没有按照题目要求分配那么多的内存空间,因为那么大输入输出不好控制。
在本程序中,输入输出与要求有出入,并没有输入进程需要的时间,而是以进程的具体内容代替,在这里又有一个假设:假设进程在CPU中每执行一步需要一个单位的时间,这样进程的大小也就等价于进程需要的时间了(排除有I/O请求的情况),个人认为这样假设比人工限定执行时间更加贴近现实情况。
@param1要找的页号
@return如果失败,返回-1.成功则返回帧号
**/
int findframe(const int& page) ;
/*打印页表*/
void printPageTable() ;
/* I/O状态信息*/
//
/*构造函数*/
PCB(const Program& p) ;
};
int PCB::findframe(const int& page)
#define TERMINATED 4
/*运行状态*/
#define INTERRUPT 2 //中断
#define NORMAL 1 //正常
#define ERROR 0 //出错
#define FINISH 1 //完成
/*时间片大小*/
#define TimeSlice 1
/*设备信息*/
int process_number ;
/*被该进程的哪一页占用*/
int page_number ;
FrameTableNode()
{
free = true ;
}
};
class FrameTable
{
public:
/*帧表*/
FrameTableNode frametable[MEMORY] ;
/*当前可用的帧的数目*/
五、心得体会
为了很好的仿真,本次试验尽可能地模拟了硬件的工作,,如输入输出设备和模拟CPU的run函数,基本上把教材77页调度问题的队列图所示功能模拟出来了,也大体实现了从用户程序到系统进程再到硬件的执行过程。
对于本次实验的核心内容——内存管理,实现了从磁盘到内存额装载过程,实现了页表的创建,实现了内存的释放。缺陷是没有考虑到换入换出等动态的情况,也就是说在此做了一个假设:每个进程相互独立且对于每个单独的进程来说,内存空间是足够大的。
程序的输入非即时的,而是通过事先设定好的5个进程加上运行后随机生成的若干进程,也是为了模拟实际情况考虑。
因为全手工输入需要输入进程的到达时间,也就是需要根据到达时间来为缓冲池中进程排序的问题,但实际情况下到达时间是多余的,先创建的先加入队列即可,所以采用了随机生成的方式。
为了此次实验,复习了调度和内存管理两章的大部分内容,对操作系统对进程调度和内存分配管理有了更深入的认识,但只是从概念上,没有看到真正操作系统的代码或者算法实例,所以可能很多地方的代码与实际情况出入很大。
/*进程状态*/
int state ;
/*程序计数器*/
int pc[2] ;
/* cpu寄存器*/
//
/* cpu调度信息*/
//
/*记账信息,这里是运行时间*/
int run_time ;
/*内存管理信息,这里就是页表*/
list<PageTableNode> PageTable ;
/**
找到程序所在页对应的帧号
}
};
/*页表节点*/
class PageTableNode
{
public:
/*页号*/
int page_number ;
/*帧号*/
int frame_number ;
PageTableNode(const int& page, const int& frame)
{
page_number = page ;
}
/**
构造函数
@param1编号
@param2内容
**/
Program(const int& n, const string& s)
{
this->number = n ;
for (int i = 0 ; i < s.size() ; i++)
v.push_back(s[i]) ;
fragmentation() ;
运行结果
在编号为1的进程中的第一个内存单位设置了一条I/O指令,可以看出其发生中断后等待I/O完成才重新回到ReadyQueue中并执行完毕。
以上结果是在内存足够大的情况,下面再看一组内存不能同时满足需求的情况
此次内存设为11帧,编号为1的进程需要10帧,编号为2的进程需要1帧,我们看到,2号进程顺利载入并执行了,但其他进程都要等到1号进程执行完释放内存后才能载入内存,符合预期情况。
{
list<PageTableNode>::iterator p = PageTable.begin() ;
while (p != PageTable.end())
{
if (page == p->page_number)
return p->frame_number ;
else
p++ ;
}
if ( p == PageTable.end())
/*********************************************************************************/
/*这个文件用来保存生成的页表的*/
ofstream outfile ;
class PCB
{
public:
/*进程编号*/
int number ;
Job_scheduler的作用如下图所示;
Job_scheduler从大容量存储设备上的缓冲池中载入新生成的进程到内存,同时生成新的PCB到就绪队列中。
这里涉及到了两个数据结构class Program,class PCB。
Program:
PCB:
PCB中的state包含五个状态NEW、READY、RUN、WAITING、TERMINATED,加入到ReadyQueue中等待运行的PCB均为READY状态的,运行中会被置为RUN,
int page_numbers ;
/*计算需要的页的数目,向下取整*/
void fragmentation()
{
page_numbers = v.size() / FRAME ;
if (page_numbers * FRAME < v.size())
page_numbers ++ ;
//cout << page_numbers << endl;
#define OFF 0
#define ON 1
/*页大小*/
#define PAGE 1
/*帧大小*/
#define FRAME 1
/*内存里面分成的帧的数目*/
#define MEMORY 11
int Memory[MEMORY * FRAME] ;
/*初始化内存*/
void InitMEM()
/***************随机数,后面随机生成进程用的*************/
void rand_seed()
{
int seed = static_cast<int>(time(0)) ;
srand(seed) ;
}
int rand_int(int a, int b)
{
return a + rand() % (b - a + 1);
}
/****************随机数,后面随机生成进程用的*************/
int AddOfIO = 0 ;
int pcr[2] = {0, 0} ;
/*进程状态*/
#define NEW 0
#define READY 1
#define RUN 2
#define WAITING 3