操作系统课程学习心得
1操作系统的功能:
主要从硬盘引导、操作系统引导、载入基本操作系统、定义临时目录、定义虚拟内存盘、载入系统服务、载入自定义服务、定义GUI这八个方面来说明针对操作系统的优化。
不管您使用的是Windows也好,Linux也好,或者是Freebsd(为避免语言烦琐,以下如同时指代Linux和FreeBSD的地方,一律以UNIX进行替代)也好,肯定都想寻求尽可能快的速度,那么,在有些特定环境下就只有对系统进行优化。在前面的几期网管笔记中,我们已经介绍了好几篇网管系列的文章,这次我们推出了操作系统的保护系列中的系统优化篇。
任何技术,只要掌握了方法则都能举一反三,“师傅领进门,修行在个人”。天极网上关于系统优化的文章相当多,但这次讲的内容和其它优化文章比起来,还是有较大的不同。各位如果在阅读下面的内容时,遇到技术疑难,都可以在天极网的操作系统栏目的相关文章中寻找到答案——学会查询资料,也是提高的必要技巧之一呢。
一个操作系统,必定是建立在硬件基础上的。而硬件,则可大致分为CPU、主板、内存、外存几个部分。关于CPU超频、内存在BIOS中的设置,开启硬盘的DMA66支持等等的介绍已经相当多,在此我就不赘述了。
一个操作系统的使用,依次会涉及到硬盘引导、操作系统引导、载入基本操作系统、定义临时目录、定义虚拟内存盘、载入系统服务、载入自定义服务、定义GUI这几个步骤,这是不管Windows、Linux还是Freebsd等操作系统都是如此。也就是说,我们如果能尽量优化上面每个步骤,则就能把系统的性能提升起来。接下来,就让我们一起把每个步骤做到最优。
主要
内容 硬盘引导
操作系统引导
载入基本操作系统
定义临时目录
定义虚拟内存盘
载入系统服务
载入自定义服务
定义GUI
2操作系统的应用:
我只说我们常见的操作系统:
微软公司出的Windows98、WindowsMe、WindowsNT、Windwos2000、WindowsXP、Windows2003。
其中,Windwos2000又分为专业版、服务器版、高级服务器版。
WindowsXP又分为家庭版、专业版,不过我们正常使用的都是专业版。
Windows2003主要是服务器用。
我们不常见的一些操作系统还有UNIT和LINUX,这两款系统主要是研究所用,或者高校讲
授《计算机操作系统》时做试验用。比较著名的LINUX系统有红帽子(RED HAT)LINUX,国内用户比较多。
WINDOWS系列与LINUX系列的主要区别是处理进程方式不一样,一个是实时系统,一个是分时系统。
————————————
目前服务器的操作系统主要有Windows2000的服务器版和Windows2000的高级服务器版,以及Windows2003的服务器版本。20xx年以前,人们还常用WindowsNT的服务器版本,只是现在被Windows2000取代。
3操作系统的分类:
简单的批处理系统--多道程序批处理系统--多道程序分时系统--微机操作系统和网络操作系统。
(1)简单的批处理系统:用户一次可以提交多个作业,但系统一次只处理一个作业,处理完一个作业后,再调入下一个作业进行处理。这些调度、切换系统自动完成。不需人工干预。
(2)多道程序批处理系统:由于简单批处理系统,一次只能处理一个作业,系统资源的利用率就不高,因此出现多道程序批处理系统,我们把同一个批次的作业调入内存,存放在内存的不同部分,当一个作业由于等待输入输出操作而让处理机出现空闲,系统自动进行切换,处理另一个作业。因此它提高了资源利用率。
批处理操作系统:特点:不需人工干预,进行批量处理。由于作业是以批量的方式进行处理的,在整个处理过程中,用户不能进行干预,这样就产生了一个问题,如果一批作业中某一个作业在处理过程中发生了错误。需要重新修改,可用户又无能为力。只能等待所有的作业都处理完成之后,才能进行修改,然后再交给计算机进行处理。因些出现了分时系统。
(3)多道程序分时系统:一个作业只能在一个时间片的时间内使用CPU,时间一到,系统将剥夺作业的CPU使用权,反CPU分配给其他作业使用。典型有UNIX操作系统。多路性(多个用户同时执行)、独占性(独立操作互不干扰)、及时性(2--3)、交互性(用户可以通过键盘输入命令请求系统服务和控制作业的)
(4)网络操作系统,,在20世纪80年代出现了网络操作系统,一台计算机只要通过一个网络接口控制器(俗称网卡)连接网络上,他可以A、进行网络通信功能,B、网络资源的管理和使用。如网络打印服务和文件服务。
一、 操作系统发展的动力
1、 提高计算机资源利用率的需要
2、 方便用户
3、 硬件设备的不断发展
4、 计算机体系结构的不断发展
二、操作系统的分类
1、 按机型分:大型机、中、小型和微型机
2、 按用户数目分:单用户操作系统和多用户操作系统
3、 按功能特征分:批处理操作系统、实时操作系统、分时操作系统。
A、微型机操作系统
◆DOS
特点:单用户单任务操作系统
◆WINDOWS
特点:单用户多任务操作系统 友好的图形用户界面、易学易用,并能支持多任务操作系统,
B、网络操作系统
特点:多用户多任务操作系统 UNIX、NETWARE、WINDOWS NT LINUX等
4操作系统中断的分类和 中断的地位:
操作系统对中断信号的处理实际是对硬件中断的一种模拟, 所以在在讨论这个问题之前, 先了解一下8086计算机硬件中断的原理。以下内容是google出来的, 出处我就不说了, 反正类似的内容多的是。
CPU在INTR引脚上接到一个中断请求信号,如果此时IF=1,CPU就会在当前指令执行完以后开始响应外部的中断请求,这时,CPU在INTA引脚连续发两个负脉冲,外设在接到第二个负脉冲以后,在数据线上发送中断类型码,接到这个中断类型码后,CPU做如下动作:
1)将中断类型码放入暂存器保存;
2)将标志寄存器内容压入堆栈,以保护中断时的状态;
3)将IF和TF标志清0。
目的是防止在中断响应的同时又来别的中断,而将TF清0是为了防止CPU以单步方式执行中断处理子程序。这时要特别提醒,因为CPU在中断响应时自动关闭了IF标志,因此用户如要进行中断嵌套时,必须在自己的中断处理子程序中用开中断指令来重新设置IF;
4)保护断点。
断点指的是在响应中断时,主程序当前指令下面的一条指令的地址。保护断点就是将当前的IP和CS的内容入栈,为了以后正确地返回主程序;
5)根据取到的中断类型码,在中断向量表中找出相应的中断向量,将其装入IP和CS,即呆自动转向中断服务子程序。
对NMI进入的中断请求,由于其类型码固定为2,因此CPU不用从外设读取类型码,也不需计算中断向量表的地址,只要将中断向量表中0000:0008H~0000:000BH单元内容分别装入IP和CS即可。
关于<.图3 中断处理过程 > 的几点说明:
1)8086/8088除软件中断外,内部“非屏蔽中断”、“可屏蔽中断”均设立有优先级,其中内中(除单步外)――即0、1、3、4号中断的优先级高于非屏蔽中断,非屏蔽中断高于可屏蔽中断,单步中断优先级最低;
2)只有在可屏蔽中断的情况下才判IF=1?,才取中断类型码,其余的没有这个动作。
3)关于单步中断,它是每执行一条指令中断一次,显示出当时各寄存器的内容,供用户参考,当进入单步中断响应时,CPU自动清除了TF,在中断返回后,由于恢复了响应时的标志寄存器的值,因此TF=1,执行完一条指令后又进入单步中断,直到程序将TF改为0为止。
4)关于中断的嵌套,NMI总是可以响应的,若在中断处理子程序中设立了开中断指令,INTR的请求也能响应。
5)弹出IP、CS、标志,返回断点的动作由IRET指令完成。
6)当遇到等待指令或串操作指令时,允许在指令执行的过程中进入中断。这时需注意在中断处理子程序中保护现场,以保证中断返回后能继续正确地执行这些指令。
扯了那么多8086的东西, 该说说正题了。操作系统在从内核态返回用户态之前(系统可能是一个系统调用, 也可能是一个时钟中断而导致进入内核模式), 将检查是否有需要的投递的信号。一旦检测到需要信号投递时, 内核将改变用户空间的数据(跟调用exec类似, 系统会改变用户空间的数据)。建立一个新的栈桢。当返回到用户空间的时候, IP指向的将是新的栈, 所以执行的下一个指令将是信号处理函数(signal_handler)。当信号出来函数返回时, 执行的将是sigreturn, 所以系统将重新进入内核模式。这个时候系统将把栈清除。恢复原来的IP值, 当重新再次返回用户模式的时候, 程序就像什么都没有发生一样继续往下执行。因为上下文是保存在用户空间, 并且是以链的形式保存, 所以信号出来的递归是没有问题的。信号处理函数sigreturn返回一次将执行一次类似弹栈操作, 直到栈为空为止。对于系统调用的自动重启, 只要把IP恢复为执行前一条指令, 那么系统调用自然自动被再次调用。不过由于带有超时参数的函数在执行signal_handler的时候会费掉时间, 再次进入系统调用将造成不必要的麻烦(两义性), 所以对于这类函数是不会自动重启的
6该课程对自己的认识:
通过一个学期对该课程的学习觉得自己学到的不光是操作系统方面的知识,感觉更多的是对各种分析方法的掌握和理解,拓宽了自己的思路有了更多的思考方式,很感谢老师对我们的谆谆教诲!
第二篇:操作系统课程 实验报告(完整版)
中 南 大 学
《操作系统》实验报告
完 成 日 期: 2011.11.22
进程调度与内存管理
一、 实验目的
在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就续进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。实验模拟实现处理机调度,以加深了解处理机调度的工作,并体会优先级和时间片轮转调度算法的具体实施方法。帮助了解在不同的存储管理方式下,应怎样实现主存空间的分配和回收。
二、实验要求
1、可随机输入若干进程,并按优先权排序;
2、从就绪队首选进程运行:优先权-1/要求运行时间-1
要求运行时间=0时,撤销该进程
3、重新排序,进行下轮调度。
4、可随时增加进程;
5、规定道数,设置后备队列和挂起状态。若内存中进程少于规定道数,可自动从后备队列调度一作业进入。被挂起进程入挂起队列,设置解挂功能用于将指定挂起进程解挂入就绪队列。
6、每次调度后,显示各进程状态。
7、自行假设主存空间大小,预设操作系统所占大小并构造未分分区表;
表目内容:起址、长度、状态(未分/空表目)
8、结合以上实验,PCB增加为:
{PID,要求运行时间,优先权,状态,所需主存大小,主存起始位置,
PCB指针}
9、采用最先适应算法分配主存空间;
10、进程完成后,回收主存,并与相邻空闲分区合并。
11、采用图形界面;
三、实验内容
选择一个调度算法,实现处理机调度。
1、设计一个按优先权调度算法实现处理机调度的程序;
2、设计按时间片轮转实现处理机调度的程序。
3、主存储器空间的分配和回收。在可变分区管理方式下,采用最先适应算法实现主存空间的分配和回收。
四、实验原理
该模拟系统采用java语言实现,要实现的功能有新建进程、进程调度、挂起进程、解挂进程、删除进程,道数和时间片大小可以由用户自己调整,有两种调度策略:按优先权调度和按时间片轮转调度。每个进程可能有5种状态:新建(new)、就绪(ready)、运行(running)、阻塞(waiting)、挂起(suspend)。每个状态都有一个队列用来存放处于该状态的进程,不同的调度策略采用不同的队列实现。当创建进程时,如果内存中的进程数还没达到规定道数,则将新建进程插入就绪队列,如果内存中进程数已经达到规定道数,则插到后备队列,后备队列中的进程的状态为new。CPU每次调度时都从就绪队列中取进程,在进程执行过程中如果下一个操作时IO操作,则将进程插入到waiting队列。在系统运行过程中可以执行进程挂起操作,但执行的挂起操作时系统自动暂停运行,在弹出窗口选择要挂起的进程后,将选中的进程从原来的队列中删除并插入到挂起队列。进行解挂操作时将选中的进程从挂起队列中删除并插入该进程原来所处的队列。
Ø 按优先级调度:
当选择按优先权调度时,所有队列都采用优先队列,优先队列采用一个有序链表实现,进程的优先权值越大代表优先级越高,优先队列中的进程按优先权从大到小排列,当新进程插入时根据该进程的优先权插入到队列中的合适位置,插入后保持队列按优先权从大到小排列,如果新进程与队列中某个进程优先权值相等,则该新进程插到那个进程后面,以遵循先来先服务的规则。当要从队列中取出进程时总是取队列中第一个进程,因为该进程的优先级最高。
Ø 按时间片轮转调度:
当选择按时间片轮转调度时,所有队列都采用先进先出队列,先进先出队列采用一个普通单向链表实现,当新进程插入时插入到队列的末尾,当要取进程时取队首进程,这样就实现了先进先出。
Ø 内存管理
该实验基于实验一完成,核心是内存的分配和回收,在实验一的基础上增加内存管理部分,在新建进程的时候增加一个输入内存大小的输入框,在进程进入内存时要分配内存,在进程销毁时要回收内存,如果进入内存时内存不足,则将进程插入到后备队列等待下次调度。系统维护一个内存表,每个表项代表一个空间,每个空间保存了该空间的起始地址和空间大小以及空间使用状态。初始时只有一个空间,当CPU启动时要分配内存,内存分配采用最先适应算法。回收内存时如果有相邻空闲空间,则要进行空闲空间合并。
}
}
五、源代码及截图:
1.divDTO:
publicclass divDTO
{
privateint divBase;
privateint length;
privateint divFlag;
public divDTO(int divBase,int length,int divFlag)
{
this.divBase = divBase;
this.divFlag = divFlag;
this.length = length;
}
public divDTO()
{
}
publicvoid setDivBase(int base)
{
this.divBase = base;
}
publicint getDivBase()
{
returnthis.divBase;
}
publicvoid setLength(int length)
{
this.length = length;
}
publicint getLength()
{
returnthis.length;
}
publicvoid setDivFlag(int flag)
{
this.divFlag = flag;
}
publicint getDivFalg()
{
returnthis.divFlag;
}
}
2.PcbDTO:
publicclass PcbDTO
{
staticfinalintRunning = 1;
staticfinalintReady = 2;
staticfinalintWaiting = 3;
private String processName;
privateint runTime;
privateint prority;
privateint processState;
privateint base;
privateint limit;
privateintpcbFlag;
public PcbDTO(String name, int time,int pro,int base,int limit)
{
this.processName = name;
this.runTime = time;
this.prority = pro;
this.processState = 0;
this.limit = limit;
this.base = base;
}
public PcbDTO()
{this.pcbFlag = 0;}
publicvoid setProcessName(String name)
{
this.processName = name;
}
public String getProcessName()
{
return processName;
}
publicvoid setRunTime(int time)
{
this.runTime = time;
}
publicint getRunTime()
{
returnthis.runTime;
}
publicvoid setPrority(int prority)
{
this.prority = prority;
}
publicint getPrority()
{
returnthis.prority;
}
publicvoid setProcessState(int state)
{
this.processState = state;
}
public String getProcessState()
{
String s = new String();
if(this.processState == 1)
{
s = "running";
}
elseif(this.processState == 2)
{
s = "ready";
}
elseif(this.processState == 3)
{
s = "waiting";
}
return s;
}
publicint getBase()
{
returnthis.base;
}
publicvoid setBase(int base)
{
this.base = base;
}
publicvoid setLimit(int limit)
{
this.limit = limit;
}
publicint getLimit()
{
returnthis.limit;
}
}
3. import javax.swing.*;
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
public class MainFrame {
private JList readyList;
private JList waitingList;
private JList jobList;
private JButton susButton;
private JButton relaxButton;
private JButton startButton;
private JButton newButton;
private JLabel nameLabel;
private JLabel prorityLabel;
private JLabel timeLabel;
private JLabel jobLabel;
private JLabel readyLabel;
private JLabel waitingLabel;
private JLabel runningLabel;
private JLabel spaceLabel;
private JLabel divLabel;
private JLabel allocLabel;
private JTable readyTable;
private JTable runningTable;
private JTable divTable;
private JTable allocTable;
private JTextField nameText;
private JTextField timeText;
private JTextField spaceText;
private JComboBox prorityCom;
private JPanel newPanel;
private JPanel waitingPanel;
private JPanel readyPanel;
Vector jobVectorName;
Vector jobDtoVector;
Vector waitingVectorName;
Vector waitingDtoVector;
PcbDTO[] readyDtoArray;
PcbDTO[] newDtoArray;
divDTO[] divDtoArray;
PcbDTO[] newSort;
Object[][] readydata;
Object[][] runningdata;
Object[][] divdata;
Object[][] allocdata;
int first;
int end;
int point;
PcbDTO a;
public MainFrame() {
a = new PcbDTO();
first = 0;
end = 0;
point = 0;
JFrame jf = new JFrame("进程调度-ws");
Container c = jf.getContentPane();
c.setLayout(null);
// c.setBackground(Color.pink);
newPanel = new JPanel();
newPanel.setLayout(null);
waitingPanel = new JPanel();
waitingPanel.setLayout(null);
// waitingPanel.setBackground(Color.pink);
readyPanel = new JPanel();
readyPanel.setLayout(null);
susButton = new JButton("挂起");
relaxButton = new JButton("释放");
startButton = new JButton("开始");
newButton = new JButton("新建进程");
nameLabel = new JLabel("进程名");
prorityLabel = new JLabel("优先级");
timeLabel = new JLabel("运行时间");
jobLabel = new JLabel("后备队列");
readyLabel = new JLabel("就绪队列");
waitingLabel = new JLabel("等待队列");
runningLabel = new JLabel("运行进程");
spaceLabel = new JLabel("需要空间");
divLabel = new JLabel("未分分区表");
allocLabel = new JLabel("内存分配表");
nameText = new JTextField();
timeText = new JTextField();
spaceText = new JTextField();
prorityCom = new JComboBox();
prorityCom.setToolTipText("优先级");
readyDtoArray = new PcbDTO[6];
newSort = new PcbDTO[6];
for (int i = 0; i < 6; i++) {
newSort[i] = new PcbDTO();
}
newDtoArray = new PcbDTO[100];
jobDtoVector = new Vector();
jobVectorName = new Vector();
waitingDtoVector = new Vector();
waitingVectorName = new Vector();
divDtoArray = new divDTO[20];
for (int i = 0; i < 20; i++) {
divDtoArray[i] = new divDTO();
divDtoArray[i].setDivFlag(0);
}
divDtoArray[0].setDivFlag(1);
divDtoArray[0].setDivBase(20);
divDtoArray[0].setLength(180);
readydata = new Object[6][4];
runningdata = new Object[2][3];
divdata = new Object[20][3];
allocdata = new Object[20][3];
String[] col1 = { "进程", "时间", "优先级", "状态" };
String[] col2 = { "进程", "时间", "优先级" };
String[] col3 = { "起址", "长度", "状态" };
String[] col4 = { "起址", "长度", "占用进程" };
readyTable = new JTable(readydata, col1);
// readyTable.setEnabled(false);
runningTable = new JTable(runningdata, col2);
runningTable.setRowHeight(22);
runningTable.setEnabled(false);
allocTable = new JTable(allocdata, col4);
allocTable.setEnabled(false);
divTable = new JTable(divdata, col3);
divTable.setEnabled(false);
divTable.setValueAt(String.valueOf(20), 0, 0);
divTable.setValueAt(String.valueOf(180), 0, 1);
divTable.setValueAt(String.valueOf(1), 0, 2);
JScrollPane runningSP = new JScrollPane();
JScrollPane readySP2 = new JScrollPane();
JScrollPane divSP = new JScrollPane();
JScrollPane allocSP = new JScrollPane();
runningSP.getViewport().add(runningTable);
readySP2.getViewport().add(readyTable);
divSP.getViewport().add(divTable);
allocSP.getViewport().add(allocTable);
// int []prorityArray = new int[10];
for (int i = 0; i < 10; i++) {
prorityCom.addItem(i);// prorityArray[i] = i;
}
jobList = new JList();
waitingList = new JList();
JScrollPane readySP = new JScrollPane(readyList);
JScrollPane jobSP = new JScrollPane(jobList);
JScrollPane waitingSP = new JScrollPane(waitingList);
newPanel.setSize(450, 100);
newPanel.setLocation(0, 0);
nameLabel.setSize(80, 20);
nameLabel.setLocation(10, 5);
nameText.setSize(100, 25);
nameText.setLocation(10, 30);
prorityLabel.setSize(80, 20);
prorityLabel.setLocation(120, 5);
prorityCom.setSize(100, 25);
prorityCom.setLocation(120, 30);
timeLabel.setSize(80, 20);
timeLabel.setLocation(230, 5);
timeText.setSize(100, 25);
timeText.setLocation(230, 30);
spaceLabel.setSize(80, 20);
spaceLabel.setLocation(340, 5);
spaceText.setSize(100, 25);
spaceText.setLocation(340, 30);
newButton.setSize(100, 20);
newButton.setLocation(320, 70);
waitingPanel.setSize(190, 410);
waitingPanel.setLocation(0, 100);
jobLabel.setSize(100, 20);
jobLabel.setLocation(10, 2);
jobSP.setSize(180, 105);
jobSP.setLocation(10, 25);
waitingLabel.setSize(100, 20);
waitingLabel.setLocation(10, 129);
waitingSP.setSize(180, 105);
waitingSP.setLocation(10, 150);
divLabel.setSize(100, 20);
divLabel.setLocation(10, 253);
divSP.setSize(180, 113);
divSP.setLocation(10, 273);
relaxButton.setSize(80, 20);
relaxButton.setLocation(110, 388);
readyPanel.setSize(260, 410);
readyPanel.setLocation(190, 100);
readyLabel.setSize(100, 22);
readyLabel.setLocation(10, 2);
allocLabel.setSize(100, 20);
allocLabel.setLocation(10, 232);
startButton.setSize(80, 20);
startButton.setLocation(177, 388);
susButton.setSize(80, 20);
susButton.setLocation(95, 388);
readySP2.setSize(250, 117);
readySP2.setLocation(10, 25);
runningLabel.setLocation(10, 142);
runningLabel.setSize(100, 20);
runningSP.setSize(250, 65);
runningSP.setLocation(10, 167);
allocSP.setSize(250, 130);
allocSP.setLocation(10, 255);
c.add(newPanel);
newPanel.add(nameLabel);
newPanel.add(nameText);
newPanel.add(prorityLabel);
newPanel.add(prorityCom);
newPanel.add(timeText);
newPanel.add(timeLabel);
newPanel.add(newButton);
newPanel.add(spaceLabel);
newPanel.add(spaceText);
c.add(waitingPanel);
waitingPanel.add(jobLabel);
waitingPanel.add(jobSP);
waitingPanel.add(waitingLabel);
waitingPanel.add(waitingSP);
waitingPanel.add(divLabel);
waitingPanel.add(divSP);
waitingPanel.add(relaxButton);
c.add(readyPanel);
readyPanel.add(readyLabel);
readyPanel.add(allocLabel);
readyPanel.add(runningLabel);
readyPanel.add(startButton);
readyPanel.add(susButton);
readyPanel.add(allocSP);
readyPanel.add(runningSP);
readyPanel.add(readySP2);
jf.setSize(470, 550);
jf.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
jf.setLocationRelativeTo(null);
jf.setVisible(true);
startButton.addActionListener(new MyActionListener());
newButton.addActionListener(new MyActionListener());
susButton.addActionListener(new MyActionListener());
relaxButton.addActionListener(new MyActionListener());
}
public void sus() {
try {
Thread.sleep(1000);
} catch (Exception ex) {
}
}
class MyActionListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
int count = 0;
PcbDTO test = new PcbDTO();
JButton jb = (JButton) e.getSource();
int max = -1;
if (jb == startButton) {
// while(true)
// {
int runAllocFlag = -1;
if ((String) runningTable.getValueAt(0, 0) == null
|| (String) runningTable.getValueAt(0, 0) == "") {
try {
Thread.sleep(0);
} catch (Exception ex) {
}
// System.out.println("到3");
for (int j = first; j != end;) {
if (!readyDtoArray[j].getProcessState().equals(
"waiting")) {
max = j;
break;
}
j = (j + 1) % 6;
}
for (int j = first; j % 6 != end;) {
if (!readyDtoArray[j].getProcessState().equals(
"waiting")) {
if (readyDtoArray[j].getPrority() > readyDtoArray[max]
.getPrority()) {
max = j;
}
}
j = (j + 1) % 6;
}
if (max >= 0) {
a = readyDtoArray[max];
readyDtoArray[max] = readyDtoArray[first];
readyDtoArray[first] = a;
readyTable.setValueAt(
readyDtoArray[max].getProcessName(), max, 0);
readyTable.setValueAt(readyDtoArray[max].getRunTime(),
max, 1);
readyTable.setValueAt(readyDtoArray[max].getPrority(),
max, 2);
readyTable.setValueAt(
readyDtoArray[max].getProcessState(), max, 3);
readyTable.setValueAt("", first, 0);
readyTable.setValueAt("", first, 1);
readyTable.setValueAt("", first, 2);
readyTable.setValueAt("", first, 3);
runningTable.setValueAt(a.getProcessName(), 0, 0);
runningTable.setValueAt(a.getRunTime(), 0, 1);
runningTable.setValueAt(a.getPrority(), 0, 2);
readyDtoArray[first].setRunTime(readyDtoArray[first]
.getRunTime() - 1);
if (0 != readyDtoArray[first].getPrority()) {
readyDtoArray[first]
.setPrority(readyDtoArray[first]
.getPrority() - 1);
}
first = (first + 1) % 6;
} else {
System.out.println("cpu等待中……");
}
} else {
/*
* try { Thread.sleep(2000); } catch(InterruptedException
* e1) { System.out.println(e1); }
*/
// System.out.println("到1");
runningTable.setValueAt("", 0, 0);
runningTable.setValueAt("", 0, 1);
runningTable.setValueAt("", 0, 2);
// 如果运行时间为0则撤销进程,否则将进程重新添加到就绪队列中
if (a.getRunTime() <= 0) {
// 收回内存空间
for (int i = 0; i < point; i++) {
if (newSort[i].getBase() >= a.getBase()) {
newSort[i] = newSort[i + 1];
}
}
point--;
// 设置内存分配表的内容
for (int i = 0; i < point; i++) {
allocTable.setValueAt(
String.valueOf(newSort[i].getBase()), i, 0);
allocTable
.setValueAt(String.valueOf(newSort[i]
.getLimit()), i, 1);
allocTable.setValueAt(newSort[i].getProcessName(),
i, 2);
}
allocTable.setValueAt("", point, 0);
allocTable.setValueAt("", point, 1);
allocTable.setValueAt("", point, 2);
// 把收回的内存加入到记录未分分区的数组
int memoryEnd = 0;
int location = 0;
int up = -1;//
int down = -1;
for (int i = 0; i < 20; i++) {
if (divDtoArray[i].getDivFalg() == 1) {
memoryEnd = divDtoArray[i].getDivBase()
+ divDtoArray[i].getLength();
if (memoryEnd == a.getBase()) {
up = i;
}
if (divDtoArray[i].getDivBase() == (a.getBase() + a
.getLimit())) {
down = i;
}
}
}
if (up >= 0 && down >= 0) {
divDtoArray[up]
.setLength((divDtoArray[up].getLength()
+ a.getLimit() + divDtoArray[down]
.getLength()));
divDtoArray[down].setDivFlag(0);
for (int i = (down + 1); i < 20; i++) {
if (divDtoArray[i].getDivFalg() == 1) {
divDtoArray[i - 1]
.setDivBase(divDtoArray[i]
.getDivBase());
divDtoArray[i - 1].setDivFlag(1);
divDtoArray[i - 1].setLength(divDtoArray[i]
.getLength());
divDtoArray[i].setDivFlag(0);
} else {
divTable.setValueAt("", i - 1, 0);
divTable.setValueAt("", i - 1, 1);
divTable.setValueAt("", i - 1, 2);
break;
}
}
} else if (up >= 0 && down < 0) {
divDtoArray[up].setLength((divDtoArray[up]
.getLength() + a.getLimit()));
} else if (up < 0 && down >= 0) {
divDtoArray[down].setLength((divDtoArray[down]
.getLength() + a.getLimit()));
divDtoArray[down].setDivBase(a.getBase());
} else if (up < 0 && down < 0) {
for (int i = 0; i < 20; i++) {
if (divDtoArray[i].getDivBase() > a.getBase()
|| divDtoArray[i].getDivFalg() == 0) {
location = i;
break;
}
}
for (int i = 20; i > location; i--) {
if (divDtoArray[i - 1].getDivFalg() == 1) {
divDtoArray[i]
.setDivBase(divDtoArray[i - 1]
.getDivBase());
divDtoArray[i].setDivFlag(1);
divDtoArray[i].setLength(divDtoArray[i - 1]
.getLength());
}
}
divDtoArray[location].setDivBase(a.getBase());
divDtoArray[location].setDivFlag(1);
divDtoArray[location].setLength(a.getLimit());
}
// 设置未分分区表的内容
for (int i = 0; i < 20; i++) {
if (divDtoArray[i].getDivFalg() == 1) {
divTable.setValueAt(String
.valueOf(divDtoArray[i].getDivBase()),
i, 0);
divTable.setValueAt(String
.valueOf(divDtoArray[i].getLength()),
i, 1);
divTable.setValueAt(String
.valueOf(divDtoArray[i].getDivFalg()),
i, 2);
}
}
if (!jobDtoVector.isEmpty()) {
int runLength = 0;
PcbDTO jobToReady = (PcbDTO) jobDtoVector
.elementAt(0);
for (int i = 0; i < 20; i++) {
if (divDtoArray[i].getDivFalg() == 1) {
if (divDtoArray[i].getLength() >= jobToReady
.getLimit()) {
runAllocFlag = i;
break;
}
}
}
if (runAllocFlag >= 0) {
jobDtoVector.removeElementAt(0);
jobVectorName.remove(jobVectorName
.indexOf(jobToReady.getProcessName()));
jobList.setListData(jobVectorName);
jobToReady.setProcessState(PcbDTO.Ready);
jobToReady.setBase(divDtoArray[runAllocFlag]
.getDivBase());
runLength = divDtoArray[runAllocFlag]
.getLength() - jobToReady.getLimit();
if (runLength == 0) {
int i = runAllocFlag;
divDtoArray[i].setDivFlag(0);
for (; i < 19; i++) {
if (divDtoArray[i + 1].getDivFalg() == 1) {
divDtoArray[i] = divDtoArray[i + 1];
divDtoArray[i + 1].setDivFlag(0);
}
divTable.setValueAt(String
.valueOf(divDtoArray[i]
.getDivBase()), i, 0);
divTable.setValueAt(String
.valueOf(divDtoArray[i]
.getLength()), i, 1);
divTable.setValueAt(String
.valueOf(divDtoArray[i]
.getDivFalg()), i, 2);
}
divTable.setValueAt(String
.valueOf(divDtoArray[i]
.getDivFalg()), i, 2);
} else if (runLength > 0) {
int c2 = divDtoArray[runAllocFlag]
.getDivBase()
+ jobToReady.getLimit();
divDtoArray[runAllocFlag].setDivBase(c2);
divDtoArray[runAllocFlag]
.setLength(runLength);
divTable.setValueAt(String.valueOf(c2),
runAllocFlag, 0);
divTable.setValueAt(
String.valueOf(runLength),
runAllocFlag, 1);
divTable.setValueAt(String
.valueOf(divDtoArray[runAllocFlag]
.getDivFalg()),
runAllocFlag, 2);
}
readyDtoArray[end] = jobToReady;
readyTable.setValueAt(
jobToReady.getProcessName(), end, 0);
readyTable.setValueAt(jobToReady.getRunTime(),
end, 1);
readyTable.setValueAt(jobToReady.getPrority(),
end, 2);
readyTable.setValueAt(
jobToReady.getProcessState(), end, 3);
end = (end + 1) % 6;
int runi = 0;// 用于记录当前新生成的PcbDTO对象应该插入到newSort中的位置
for (; runi < point; runi++) {
if (jobToReady.getBase() < newSort[runi]
.getBase()) {
break;
}
}
// 如果不是插入到数组末尾,则把比它大的都向后挪一位并设置JTable中的显示
for (int i = point; i > runi; i--) {
newSort[i] = newSort[i - 1];
allocTable.setValueAt(String
.valueOf(newSort[i].getBase()), i,
0);
allocTable.setValueAt(String
.valueOf(newSort[i].getLimit()), i,
1);
allocTable.setValueAt(
newSort[i].getProcessName(), i, 2);
}
// 插入新生成的对象
newSort[runi] = jobToReady;
allocTable.setValueAt(
String.valueOf(jobToReady.getBase()),
runi, 0);
allocTable.setValueAt(
String.valueOf(jobToReady.getLimit()),
runi, 1);
allocTable.setValueAt(
jobToReady.getProcessName(), runi, 2);
point++;
}
}
} else {
readyDtoArray[end] = a;
readyTable.setValueAt(a.getProcessName(), end, 0);
readyTable.setValueAt(a.getRunTime(), end, 1);
readyTable.setValueAt(a.getPrority(), end, 2);
readyTable.setValueAt(a.getProcessState(), end, 3);
end = (end + 1) % 6;
}
}
// }
} else if (jb == newButton) {
int newAllocFlag = -1;
int newLength = 0;
if (nameText.getText().trim().length() == 0) {
JOptionPane.showMessageDialog(null, "进程名不能为空!");
} else if (timeText.getText().trim().length() == 0) {
JOptionPane.showMessageDialog(null, "运行时间不能为空");
} else if (spaceText.getText().trim().length() == 0) {
JOptionPane.showMessageDialog(null, "空间不能为空");
} else {
test.setRunTime(Integer.parseInt(timeText.getText()));
test.setLimit(Integer.parseInt(spaceText.getText()));
String s = prorityCom.getSelectedItem().toString();
test.setPrority(Integer.parseInt(s));
test.setProcessName(nameText.getText().trim());
newDtoArray[count] = test;
jobDtoVector.add(newDtoArray[count]);
jobVectorName.add(newDtoArray[count].getProcessName());
jobList.setListData(jobVectorName);
count++;
nameText.setText("");
timeText.setText("");
spaceText.setText("");
PcbDTO b = (PcbDTO) jobDtoVector.elementAt(0);
for (int i = 0; i < 20; i++) {
if (divDtoArray[i].getDivFalg() == 1) {
if (divDtoArray[i].getLength() >= b.getLimit()) {
newAllocFlag = i;
break;
}
}
}
// 在就绪队列未满且内存有足够空间时将后备队列jobDtoVetor中的对象添加到就绪队列中
if ((end + 2) % 6 != first && newAllocFlag >= 0) {
jobDtoVector.removeElementAt(0);
b.setProcessState(PcbDTO.Ready);
b.setBase(divDtoArray[newAllocFlag].getDivBase());
newLength = divDtoArray[newAllocFlag].getLength()
- b.getLimit();
if (newLength == 0) {
int i = newAllocFlag;
divDtoArray[i].setDivFlag(0);
for (; i < 19; i++) {
if (divDtoArray[i + 1].getDivFalg() == 1) {
divDtoArray[i] = divDtoArray[i + 1];
divDtoArray[i + 1].setDivFlag(0);
}
divTable.setValueAt(String
.valueOf(divDtoArray[i].getDivBase()),
i, 0);
divTable.setValueAt(String
.valueOf(divDtoArray[i].getLength()),
i, 1);
divTable.setValueAt(String
.valueOf(divDtoArray[i].getDivFalg()),
i, 2);
}
divTable.setValueAt(
String.valueOf(divDtoArray[i].getDivFalg()),
i, 2);
} else if (newLength > 0) {
int c1 = divDtoArray[newAllocFlag].getDivBase()
+ b.getLimit();
divDtoArray[newAllocFlag].setDivBase(c1);
divDtoArray[newAllocFlag].setLength(newLength);
divTable.setValueAt(String.valueOf(c1),
newAllocFlag, 0);
divTable.setValueAt(String.valueOf(newLength),
newAllocFlag, 1);
divTable.setValueAt(String
.valueOf(divDtoArray[newAllocFlag]
.getDivFalg()), newAllocFlag, 2);
}
readyDtoArray[end] = b;
jobVectorName.remove(jobVectorName.indexOf(b
.getProcessName()));
readyTable.setValueAt(b.getProcessName(), end, 0);
readyTable.setValueAt(b.getRunTime(), end, 1);
readyTable.setValueAt(b.getPrority(), end, 2);
readyTable.setValueAt("ready", end, 3);
end = (end + 1) % 6;
int newi = 0;// 用于记录当前新生成的PcbDTO对象应该插入到newSort中的位置
for (; newi < point; newi++) {
if (b.getBase() < newSort[newi].getBase()) {
break;
}
}
// 如果不是插入到数组末尾,则把比它大的都向后挪一位并设置JTable中的显示
for (int i = point; i > newi; i--) {
newSort[i] = newSort[i - 1];
allocTable.setValueAt(
String.valueOf(newSort[i].getBase()), i, 0);
allocTable
.setValueAt(String.valueOf(newSort[i]
.getLimit()), i, 1);
allocTable.setValueAt(newSort[i].getProcessName(),
i, 2);
}
// 插入新生成的对象
newSort[newi] = b;
allocTable.setValueAt(String.valueOf(b.getBase()),
newi, 0);
allocTable.setValueAt(String.valueOf(b.getLimit()),
newi, 1);
allocTable.setValueAt(b.getProcessName(), newi, 2);
point++;
}
}
} else if (jb == susButton) {
if (readyDtoArray[readyTable.getSelectedRow()] != null) {
if (!readyDtoArray[readyTable.getSelectedRow()]
.getProcessState().equals("waiting")) {
readyDtoArray[readyTable.getSelectedRow()]
.setProcessState(PcbDTO.Waiting);
readyTable.setValueAt("waiting",
readyTable.getSelectedRow(), 3);
waitingDtoVector.add(readyDtoArray[readyTable
.getSelectedRow()]);
waitingVectorName.add(readyDtoArray[readyTable
.getSelectedRow()].getProcessName());
waitingList.setListData(waitingVectorName);
} else {
System.out.println("已挂起");
}
} else {
JOptionPane.showMessageDialog(null, "请选择要挂起的进程");
// System.out.println("请选择要挂起的进程");
}
} else if (jb == relaxButton) {
String s = (String) waitingList.getSelectedValue();
if (s != null) {
waitingVectorName.remove(s);
PcbDTO p = new PcbDTO();
for (int i = 0; i < waitingDtoVector.size(); i++) {
p = (PcbDTO) waitingDtoVector.elementAt(i);
if (s.equals(p.getProcessName())) {
p.setProcessState(PcbDTO.Ready);
waitingDtoVector.remove(p);
break;
}
}
for (int i = 0; i < 6; i++) {
if (s.equals(readyDtoArray[i].getProcessName())) {
readyTable.setValueAt("ready", i, 3);
break;
}
}
waitingList.setListData(waitingVectorName);
} else {
JOptionPane.showMessageDialog(null, "请选择要解挂的进程");
// System.out.println("没有选择的进程");
}
}
}
}
public static void main(String args[]) {
new MainFrame();
}
}
运行截图:
运行后开始界面 输入进程后界面
建立后挂起 挂起后各内存分配
解挂
操作异常时的提示
六、实验总结
这个程序,我参考了课本,互联网以及相关资料。由于对java语言比较陌生,因此虽然这个试验比较简单,并且不是我一人独立完成,但也花费了我大量时间。通过这个实验,我更加形象的了解了进程的调度过程,加深了对于优先权调度和时间片轮转调度的理解,并不像从前一样仅仅停留在概念上。除此之外让我对java语言也有了进一步的了解。通过次实验,我对内存分配和内存回收有了更深刻的了解,我们平时用电脑时简单的一个动作对内存来说却要做出如此多的反应,找到一个空闲并且大小合适的空间进行内存分配。本次实验使我对内存分配的了解有了很大的帮助。在这次编程中我也出现了很多程序上的简单错误,都是因为我动手写程序比较少造成的,这也让我了解到,要多次锻炼才能顺心顺手。