当前位置:文档之家› 操作系统实验-CPU进程调度和内存分配 java版

操作系统实验-CPU进程调度和内存分配 java版

操作系统实验-CPU进程调度和内存分配 java版
操作系统实验-CPU进程调度和内存分配 java版

操作系统实验

第一期项目开发实现

实验名称EXP.1 CPU Scheduling

Exp.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方法取得数组的迭代器;

(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.java

package 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 " ";

else

return this.PID;

}

public void setPID(String pid) {

if(pid == null)

this.PID = " ";

else

this.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" ";

else

return this.Status;

}

public void setStatues(String statues) { if(statues == null)

this.Status = " ";

else

this.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.java

package 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.java

package src;

import java.util.ArrayList;

import java.util.Iterator;

public class PCBRecords implements Iterable { private ArrayList PCBItems;

public ArrayList getPCBItems() {

return this.PCBItems;

}

public PCBRecords() {

this.PCBItems = new ArrayList();

}

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 iterator() {

return this.PCBItems.iterator();

}

MemoryRecords.java

package src;

import java.util.ArrayList;

import java.util.Iterator;

public class MemoryRecords implements Iterable {

private ArrayList memoryItems;

public Iterator iterator() {

// TODO Auto-generated method stub

return this.memoryItems.iterator();

}

public ArrayList getMemoryItems() {

return this.memoryItems;

}

public MemoryRecords() {

this.memoryItems = new ArrayList();

}

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.Java

import 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; //各队列相对应的数组列表

// 进程添加框中的"添加至后备队列","添加至就绪队列","重置"Button

private JButton addToBAKButton, addToReadyButton, resetButton;

//就绪队列框中的"挂起",挂起队列框中的"解挂","删除"Button

private JButton suspendButton, umountButton, removeButton;

//Status面板中的"启动系统","重置系统"Button

private 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,所需内存大小limit

private 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 stub

new 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 Panel

PCBItemPanel = 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 Panel

backupBAKPanel = 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 Panel

suspendedPanel = 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 panel

JPanel 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.CENTER

readyListPanel.add (suspendButton, BorderLayout.SOUTH);

// CPU panel

JPanel 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 window

setLayout(new BorderLayout());

add(northPanel, BorderLayout.NORTH);

add(centrelPanel, BorderLayout.CENTER);

add(southPanel, BorderLayout.SOUTH); //statuesPanel

// start listening for list and buttons events

addToBAKButton.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 resetButton events.

*/

class ResetListener implements ActionListener {

public void actionPerformed(ActionEvent event) {

reset();

}

}

/**

* This inner class processes suspendButton 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) {

操作系统实验报告--实验一--进程管理

实验一进程管理 一、目的 进程调度是处理机管理的核心内容。本实验要求编写和调试一个简单的进程调度程序。通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实施办法。 二、实验内容及要求 1、设计进程控制块PCB的结构(PCB结构通常包括以下信息:进程名(进程ID)、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等。可根据实验的不同,PCB结构的内容可以作适当的增删)。为了便于处理,程序中的某进程运行时间以时间片为单位计算。各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定。 2、系统资源(r1…r w),共有w类,每类数目为r1…r w。随机产生n进程P i(id,s(j,k),t),0<=i<=n,0<=j<=m,0<=k<=dt为总运行时间,在运行过程中,会随机申请新的资源。 3、每个进程可有三个状态(即就绪状态W、运行状态R、等待或阻塞状态B),并假设初始状态为就绪状态。建立进程就绪队列。 4、编制进程调度算法:时间片轮转调度算法 本程序用该算法对n个进程进行调度,进程每执行一次,CPU时间片数加1,进程还需要的时间片数减1。在调度算法中,采用固定时间片(即:每执行一次进程,该进程的执行时间片数为已执行了1个单位),这时,CPU时间片数加1,进程还需要的时间片数减1,并排列到就绪队列的尾上。 三、实验环境 操作系统环境:Windows系统。 编程语言:C#。 四、实验思路和设计 1、程序流程图

2、主要程序代码 //PCB结构体 struct pcb { public int id; //进程ID public int ra; //所需资源A的数量 public int rb; //所需资源B的数量 public int rc; //所需资源C的数量 public int ntime; //所需的时间片个数 public int rtime; //已经运行的时间片个数 public char state; //进程状态,W(等待)、R(运行)、B(阻塞) //public int next; } ArrayList hready = new ArrayList(); ArrayList hblock = new ArrayList(); Random random = new Random(); //ArrayList p = new ArrayList(); int m, n, r, a,a1, b,b1, c,c1, h = 0, i = 1, time1Inteval;//m为要模拟的进程个数,n为初始化进程个数 //r为可随机产生的进程数(r=m-n) //a,b,c分别为A,B,C三类资源的总量 //i为进城计数,i=1…n //h为运行的时间片次数,time1Inteval为时间片大小(毫秒) //对进程进行初始化,建立就绪数组、阻塞数组。 public void input()//对进程进行初始化,建立就绪队列、阻塞队列 { m = int.Parse(textBox4.Text); n = int.Parse(textBox5.Text); a = int.Parse(textBox6.Text); b = int.Parse(textBox7.Text); c = int.Parse(textBox8.Text); a1 = a; b1 = b; c1 = c; r = m - n; time1Inteval = int.Parse(textBox9.Text); timer1.Interval = time1Inteval; for (i = 1; i <= n; i++) { pcb jincheng = new pcb(); jincheng.id = i; jincheng.ra = (random.Next(a) + 1); jincheng.rb = (random.Next(b) + 1); jincheng.rc = (random.Next(c) + 1); jincheng.ntime = (random.Next(1, 5)); jincheng.rtime = 0;

操作系统磁盘调度算法实验报告

《操作系统原理》 课程设计报告书 题目:磁盘调度 专业:网络工程 学号: 学生姓名: 指导教师: 完成日期:

目录 第一章课程设计目的 (1) 1.1编写目的 (1) 第二章课程设计内容 (2) 2.1设计内容 (2) 2.1.1、先来先服务算法(FCFS) (2) 2.1.2、最短寻道时间优先算法(SSTF) (2) 2.1.3、扫描算法(SCAN) (3) 2.1.4、循环扫描算法(CSCAN) (3) 第三章系统概要设计 (4) 3.1模块调度关系图 (4) 3.2模块程序流程图 (4) 3.2.1 FCFS算法 (5) 3.2.2 SSTF算法 (6) 3.2.3 SCAN算法 (7) 3.2.4 CSCAN算法 (8) 第四章程序实现 (9) 4.1 主函数的代码实现 (9) 4.2.FCFS算法的代码实现 (11) 4.3 SSTF算法的代码实现 (13) 4.4 SCAN算法的代码实现 (15) 4.5 CSCAN算法的代码实现 (17) 第五章测试数据和结果 (20) 第六章总结 (23)

第一章课程设计目的 1.1编写目的 本课程设计的目的是通过磁盘调度算法设计一个磁盘调度模拟系统,从而使磁盘调度算法更加形象化,容易使人理解,使磁盘调度的特点更简单明了,能使使用者加深对先来先服务算法、最短寻道时间优先算法、扫描算法以及循环扫描算法等磁盘调度算法的理解 1

第二章课程设计内容 2.1设计内容 系统主界面可以灵活选择某种算法,算法包括:先来先服务算法(FCFS)、最短寻道时间优先算法(SSTF)、扫描算法(SCAN)、循环扫描算法(CSCAN)。 2.1.1、先来先服务算法(FCFS) 这是一种比较简单的磁盘调度算法。它根据进程请求访问磁盘的先后次序进行调度。此算法的优点是公平、简单,且每个进程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。此算法由于未对寻道进行优化,在对磁盘的访问请求比较多的情况下,此算法将降低设备服务的吞吐量,致使平均寻道时间可能较长,但各进程得到服务的响应时间的变化幅度较小。 2.1.2、最短寻道时间优先算法(SSTF) 该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,该算法可以得到比较好的吞吐量,但却不能保证平均寻道时间最短。其缺点是对用户的服务请求的响应机会不是均等的,因而导致响应时间的变化幅度很大。在服务请求很多的情况下,对内外边缘磁道的请求将会无限期的被延迟,有些请求的响应时间将不可预期。 2

操作系统实验内存分配

西安邮电大学 (计算机学院) 课内实验报告 实验名称:内存管理 专业名称:软件工程 班级: 学生姓名: 学号(8位): 指导教师: 实验日期:

实验五:进程 1.实验目的 通过深入理解区管理的三种算法,定义相应的数据结构,编写具体代码。充分模拟三种算法的实现过程,并通过对比,分析三种算法的优劣。 (1)掌握内存分配FF,BF,WF策略及实现的思路; (2)掌握内存回收过程及实现思路; (3)参考给出的代码思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。 2.实验要求: 1)掌握内存分配FF,BF,WF策略及实现的思路; 2)掌握内存回收过程及实现思路; 3)参考本程序思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。 3.实验过程: 创建进程:

删除其中几个进程:(默认以ff首次适应算法方式排列) Bf最佳适应算法排列方式:

wf最差匹配算法排列方式: 4.实验心得: 这次实验实验时间比较长,而且实验指导书中对内存的管理讲的很详细,老师上课的时候也有讲的很详细,但是代码比较长,刚开始的时候也是不太懂,但是后面经过和同学一起商讨,明白几种算法的含义: ①首次适应算法。在采用空闲分区链作为数据结构时,该算法要求空闲分区链表以地址递增的次序链接。在进行内存分配时,从链首开始顺序查找,直至找到一个能满足进程大小要求的空闲分区为止。然后,再按照进程请求内存的大小,从该分区中划出一块内存空间分配给请求进程,余下的空闲分区仍留在空闲链中。 ②循环首次适应算法。该算法是由首次适应算法演变而形成的,在为进程分配内存空间时,从上次找到的空闲分区的下一个空闲分区开始查找,直至找到第一个能满足要求的空闲分区,并从中划出一块与请求的大小相等的内存空间分配给进程。 ③最佳适应算法将空闲分区链表按分区大小由小到大排序,在链表中查找第一个满足要求的分区。 ④最差匹配算法将空闲分区链表按分区大小由大到小排序,在链表中找到第一个满足要求的空闲分区。 实验中没有用到循环首次适应算法,但是对其他三种的描述还是很详细,总的来说,从实验中还是学到了很多。 5.程序源代码: #include #include #include

操作系统的进程调度 实验报告

《计算机操作系统2》实验报告 实验一题目:操作系统的进程调度 姓名:学号:12125807 实验日期:2014.12 实验要求: 1.设计一个有n个进程工行的进程调度程序。每个进程由一个进程控制块(PCB)表示。 进程控制块通常应包含下述信息:进程名、进程优先数、进程需要运行的时间、占用CPU的时间以及进程的状态等,且可按调度算法的不同而增删。 2.调度程序应包含2~3种不同的调度算法,运行时可任意选一种,以利于各种算法的分 析比较。 3.系统应能显示或打印各进程状态和参数的变化情况,便于观察诸进程的调度过程 实验目的: 1.进程是操作系统最重要的概念之一,进程调度又是操作系统核心的主要内容。本实习要 求学生独立地用高级语言编写和调试一个简单的进程调度程序。调度算法可任意选择或自行设计。例如,简单轮转法和优先数法等。本实习可加深对于进程调度和各种调度算法的理解。 实验内容: 1.编制和调试示例给出的进程调度程序,并使其投入运行。 2.自行设计或改写一个进程调度程序,在相应机器上调试和运行该程序,其功能应该不亚 于示例。 3.直观地评测各种调度算法的性能。 示例: 1.题目 本程序可选用优先数法或简单轮转法对五个进程进行调度。每个进程处于运行R(run)、就绪W(wait)和完成F(finish)三种状态之一,并假设起始状态都是就绪状态W。为了便于处理,程序进程的运行时间以时间片为单位计算。各进程的优先数或轮转时间片数、以及进程需要运行的时间片数,均由伪随机数发生器产生。 进程控制块结构如下:

PCB 进程标识数 链指针 优先数/轮转时间片数 占用CPU时间片数 进程所需时间片数 进程状态 进程控制块链结构如下: 其中:RUN—当前运行进程指针; HEAD—进程就绪链链首指针; TAID—进程就绪链链尾指针。 2.算法与框图 (1) 优先数法。 进程就绪链按优先数大小从高到低排列,链首进程首先投入运行。每过一个时间片,运行进程所需运行的时间片数减1,说明它已运行了一个时间片,优先数也减3,理由是该进程如果在一个时间片中完成不了,优先级应该降低一级。接着比较现行进程和就绪链链首进程的优先数,如果仍是现行进程高或者相同,就让现行进程继续进行,否则,调度就绪链链首进程投入运行。原运行进程再按其优先数大小插入就绪链,且改变它们对应的进程状态,直至所有进程都运行完各自的时间片数。 (2) 简单轮转法。 进程就绪链按各进程进入的先后次序排列,进程每次占用处理机的轮转时间按其重要程度登入进程控制块中的轮转时间片数记录项(相当于优先数法的优先数记录项位置)。每过一个时间片,运行进程占用处理机的时间片数加1,然后比较占用处理机的时间片数是否与该进程的轮转时间片数相等,若相等说明已到达轮转时间,应将现运行进程排到就绪链末尾,调度链首进程占用处理机,且改变它们的进程状态,直至所有进程完成各自的时间片。(3) 程序框图如下图所示。

操作系统实验报告(进程调度算法)

操作系统实验报告(进程调度算法)

实验1 进程调度算法 一、实验内容 按优先数调度算法实现处理器调度。 二、实验目的 在采用多道程序设计的系统中,往往有若干个进程同时处于就绪状态。当就绪进程个数大于处理器数时,就必须依照某种策略来决定哪些进程优先占用处理器。本实验模拟在单处理器情况下的处理器调度,帮助学生加深了解处理器调度的工作。 三、实验原理 设计一个按优先数调度算法实现处理器调度的程序。 (1) 假定系统有五个进程,每一个进程用一个进程控制块PCB来代表,进程控制块的格式为: 进程名 指针 要求运行时 间 优先数

状态 其中,进程名——作为进程的标识,假设五个进程的进程名分别为P1,P2,P3,P4,P5。 指针——按优先数的大小把五个进程连成队列,用指针指出下一个进程的进程控制块的首地址,最后一个进程中的指针为“0”。 要求运行时间——假设进程需要运行的单位时间数。 优先数——赋予进程的优先数,调度时总是选取优先数大的进程先执行。 状态——可假设有两种状态,“就绪”状态和“结束”状态。五个进程的初始状态都为“就绪”,用“R”表示,当一个进程运行结束后,它的状态为“结束”,用“E”表示。 (2) 在每次运行你所设计的处理器调度程序之前,为每个进程任意确定它的“优先数”和“要求运行时间”。 (3) 为了调度方便,把五个进程按给定的优先数从大到小连成队列。用一单元指出队首进程,用指针指出队列的连接情况。例: 队首标志 K2

1P1 K 2 P2 K 3 P3 K 4 P4 K 5 P5 0 K4K5K3K1 2 3 1 2 4 1 5 3 4 2 R R R R R PC B1 PC B2 PC B3 PC B4 PC B5 (4) 处理器调度总是选队首进程运行。采用动态改变优先数的办法,进程每运行一次优先数就减“1”。由于本实验是模拟处理器调度,所以,对被选中的进程并不实际的启动运行,而是执行: 优先数-1 要求运行时间-1 来模拟进程的一次运行。 提醒注意的是:在实际的系统中,当一个进程被选中运行时,必须恢复进程的现场,让它占有处理器运行,直到出现等待事件或运行结束。在这里省去了这些工作。

操作系统磁盘调度算法实验报告

操作系统磁盘调度算法 实验报告 Company number:【0089WT-8898YT-W8CCB-BUUT-202108】

目录

1.课程设计目的 编写目的 本课程设计的目的是通过磁盘调度算法设计一个磁盘调度模拟系统,从而使磁盘调度算法更加形象化,容易使人理解,使磁盘调度的特点更简单明了,能使使用者加深对先来先服务算法、最短寻道时间优先算法、扫描算法以及循环扫描算法等磁盘调度算法的理解。 2.课程设计内容 设计内容 系统主界面可以灵活选择某种算法,算法包括:先来先服务算法(FCFS)、最短寻道时间优先算法(SSTF)、扫描算法(SCAN)、循环扫描算法(CSCAN)。 1、先来先服务算法(FCFS) 这是一种比较简单的磁盘调度算法。它根据进程请求访问磁盘的先后次序进行调度。此算法的优点是公平、简单,且每个进

程的请求都能依次得到处理,不会出现某一进程的请求长期得不到满足的情况。此算法由于未对寻道进行优化,在对磁盘的访问请求比较多的情况下,此算法将降低设备服务的吞吐量,致使平均寻道时间可能较长,但各进程得到服务的响应时间的变化幅度较小。 2、最短寻道时间优先算法(SSTF) 该算法选择这样的进程,其要求访问的磁道与当前磁头所在的磁道距离最近,以使每次的寻道时间最短,该算法可以得到比较好的吞吐量,但却不能保证平均寻道时间最短。其缺点是对用户的服务请求的响应机会不是均等的,因而导致响应时间的变化幅度很大。在服务请求很多的情况下,对内外边缘磁道的请求将会无限期的被延迟,有些请求的响应时间将不可预期。 3、扫描算法(SCAN) 扫描算法不仅考虑到欲访问的磁道与当前磁道的距离,更优先考虑的是磁头的当前移动方向。例如,当磁头正在自里向外移动时,扫描算法所选择的下一个访问对象应是其欲访问的磁道既在当前磁道之外,又是距离最近的。这样自里向外地访问,直到

嵌入式系统中,动态分配内存可能发生的问题是什么

嵌入式系统中,动态分配内存可能发生的 问题是什么 中断是嵌入式系统中重要的组成部分,这导致了很多编译开发商提供一种扩展—让标准C支持中断。具代表事实是,产生了一个新的关键字__interrupt。下面的代码就使用了__interrupt关键字去定义了一个中断服务子程序(ISR),请评论一下这段代码的。__interrupt do 1.压控振荡器的英文缩写。2.动态随机存储器的英文缩写。3.选择电阻时要考虑什么?4.单片机上电后没有运转,首先要检查什么?5.计算机的基本组成部分及其各自的作用。6.怎样用D 触发器、与或非门组成二分频电路? 这个问题用几个解决方案。我首选的方案是:while(1) { } 一些程序员更喜欢如下方案:for(;;) { } 这个实现方式让我为难,因为这个语法没有确切表达到底怎么回事。如果一个应试者给出这个作为方案,我将用这个作为一个机会去探究他们这样做的基本原理。如果一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:1).

回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。嵌入式系统程序员经常同硬件、中断、RTOS等等打交道,所用这些都要求volatile变量。不懂得volatile内容将会带来灾难。假设被面试者正确地回答了这是问题(嗯, 尽管不像非嵌入式计算机那么常见,嵌入式系统还是有从堆(heap)中动态分配内存的过程的。那么嵌入式系统中,动态分配内存可能发生的问题是什么?这里,我期望应试者能提到内存碎片,碎片收集的问题,变量的持行时间等等。这个主题已经在ESP杂志中被广泛地讨

操作系统实验之内存管理实验报告

学生学号 实验课成绩 武汉理工大学 学生实验报告书 实验课程名称 计算机操作系统 开 课 学 院 计算机科学与技术学院 指导老师姓名 学 生 姓 名 学生专业班级 2016 — 2017 学年第一学期

实验三 内存管理 一、设计目的、功能与要求 1、实验目的 掌握内存管理的相关内容,对内存的分配和回收有深入的理解。 2、实现功能 模拟实现内存管理机制 3、具体要求 任选一种计算机高级语言编程实现 选择一种内存管理方案:动态分区式、请求页式、段式、段页式等 能够输入给定的内存大小,进程的个数,每个进程所需内存空间的大小等 能够选择分配、回收操作 内购显示进程在内存的储存地址、大小等 显示每次完成内存分配或回收后内存空间的使用情况 二、问题描述 所谓分区,是把内存分为一些大小相等或不等的分区,除操作系统占用一个分区外,其余分区用来存放进程的程序和数据。本次实验中才用动态分区法,也就是在作业的处理过程中划分内存的区域,根据需要确定大小。 动态分区的分配算法:首先从可用表/自由链中找到一个足以容纳该作业的可用空白区,如果这个空白区比需求大,则将它分为两个部分,一部分成为已分配区,剩下部分仍为空白区。最后修改可用表或自由链,并回送一个所分配区的序号或该分区的起始地址。 最先适应法:按分区的起始地址的递增次序,从头查找,找到符合要求的第一个分区。

最佳适应法:按照分区大小的递增次序,查找,找到符合要求的第一个分区。 最坏适应法:按分区大小的递减次序,从头查找,找到符合要求的第一个分区。 三、数据结构及功能设计 1、数据结构 定义空闲分区结构体,用来保存内存中空闲分区的情况。其中size属性表示空闲分区的大小,start_addr表示空闲分区首地址,next指针指向下一个空闲分区。 //空闲分区 typedef struct Free_Block { int size; int start_addr; struct Free_Block *next; } Free_Block; Free_Block *free_block; 定义已分配的内存空间的结构体,用来保存已经被进程占用了内存空间的情况。其中pid作为该被分配分区的编号,用于在释放该内存空间时便于查找。size表示分区的大小,start_addr表示分区的起始地址,process_name存放进程名称,next指针指向下一个分区。 //已分配分区的结构体 typedef struct Allocate_Block { int pid; int size; int start_addr; char process_name[PROCESS_NAME_LEN]; struct Allocate_Block *next; } Allocate_Block; 2、模块说明 2.1 初始化模块 对内存空间进行初始化,初始情况内存空间为空,但是要设置内存的最大容量,该内存空间的首地址,以便之后新建进程的过程中使用。当空闲分区初始化

操作系统内存动态分配模拟算法

实验四存分配算法 1.实验目的 一个好的计算机系统不仅要有一个足够容量的、存取速度高的、稳定可靠的主存储器,而且要能合理地分配和使用这些存储空间。当用户提出申请主存储器空间时,存储管理必须根据申请者的要求,按一定的策略分析主存空间的使用情况,找出足够的空闲区域分配给申请者。当作业撤离或主动归还主存资源时,则存储管理要收回作业占用的主存空间或归还部分主存空间。主存的分配和回收的实现是与主存储器的管理方式有关的,通过本实验帮助学生理解在动态分区管理方式下应怎样实现主存空间的分配和回收。 背景知识: 可变分区方式是按作业需要的主存空间大小来分割分区的。当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入。随着作业的装入、撤离、主存空间被分成许多个分区,有的分区被作业占用,而有的分区是空闲的。 2.实验容 采用首次适应算法或循环首次算法或最佳适应算法分配主存空间。 由于本实验是模拟主存的分配,所以当把主存区分配给作业后并不实际启动装入程序装入作业,而用输出“分配情况”来代替。(即输出当时的空闲区说明表及其存分配表) 利用VC++6.0实现上述程序设计和调试操作。 3.实验代码 #include #include using namespace std; //定义存的大小 const int SIZE=64; //作业结构体,保存作业信息 struct Project{ int number; int length; }; //存块结构体,保存存块信息 struct Block{

操作系统原理-进程调度实验报告

一、实验目的 通过对进程调度算法的设计,深入理解进程调度的原理。 进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。 进程调度分配处理机,是控制协调进程对CPU的竞争,即按一定的调度算法从就绪队列中选中一个进程,把CPU的使用权交给被选中的进程。 进程通过定义一个进程控制块的数据结构(PCB)来表示;每个进程需要赋予进程ID、进程到达时间、进程需要运行的总时间的属性;在RR中,以1为时间片单位;运行时,输入若干个进程序列,按照时间片输出其执行序列。 二、实验环境 VC++6.0 三、实验内容 实现短进程优先调度算法(SPF)和时间片轮转调度算法(RR) [提示]: (1) 先来先服务(FCFS)调度算法 原理:每次调度是从就绪队列中,选择一个最先进入就绪队列的进程,把处理器分配给该进程,使之得到执行。该进程一旦占有了处理器,它就一直运行下去,直到该进程完成或因发生事件而阻塞,才退出处理器。 将用户作业和就绪进程按提交顺序或变为就绪状态的先后排成队列,并按照先来先服务的方式进行调度处理,是一种最普遍和最简单的方法。它优先考虑在系统中等待时间最长的作业,而不管要求运行时间的长短。 按照就绪进程进入就绪队列的先后次序进行调度,简单易实现,利于长进程,CPU繁忙型作业,不利于短进程,排队时间相对过长。 (2) 时间片轮转调度算法RR

原理:时间片轮转法主要用于进程调度。采用此算法的系统,其程序就绪队列往往按进程到达的时间来排序。进程调度按一定时间片(q)轮番运行各个进程. 进程按到达时间在就绪队列中排队,调度程序每次把CPU分配给就绪队列首进程使用一个时间片,运行完一个时间片释放CPU,排到就绪队列末尾参加下一轮调度,CPU分配给就绪队列的首进程。 固定时间片轮转法: 1 所有就绪进程按 FCFS 规则排队。 2 处理机总是分配给就绪队列的队首进程。 3 如果运行的进程用完时间片,则系统就把该进程送回就绪队列的队尾,重新排队。 4 因等待某事件而阻塞的进程送到阻塞队列。 5 系统把被唤醒的进程送到就绪队列的队尾。 可变时间片轮转法: 1 进程状态的转换方法同固定时间片轮转法。 2 响应时间固定,时间片的长短依据进程数量的多少由T = N × ( q + t )给出的关系调整。 3 根据进程优先级的高低进一步调整时间片,优先级越高的进程,分配的时间片越长。 多就绪队列轮转法: (3) 算法类型 (4)模拟程序可由两部分组成,先来先服务(FCFS)调度算法,时间片轮转。流程图如下:

天津理工大学操作系统实验3:磁盘调度算法的实现

人和以吟实验报告学院(系)名称:计算机与通信工程学院

【实验过程记录(源程序、测试用例、测试结果及心得体会等) 】 #include #include #include using namespace std; void Inith() { cout<<" 请输入磁道数: "; cin>>M; cout<<" 请输入提出磁盘 I/O 申请的进程数 cin>>N; cout<<" 请依次输入要访问的磁道号: "; for(int i=0;i>TrackOrder[i]; for(int j=0;j>BeginNum; for(int k=0;k=0;i--) for(int j=0;jSortOrder[j+1]) const int MaxNumber=100; int TrackOrder[MaxNumber]; int MoveDistance[MaxNumber]; // ------- int FindOrder[MaxNumber]; // ---------- double AverageDistance; // ----------- bool direction; // int BeginNum; // int M; // int N; // int SortOrder[MaxNumber]; // ------ bool Finished[MaxNumber]; 移动距离 ; 寻好序列。 平均寻道长度 方向 true 时为向外, false 开始磁道号。 磁道数。 提出磁盘 I/O 申请的进程数 排序后的序列 为向里

《动态分配内存与数据结构》课后习题

《动态分配内存与数据结构》习题 学号姓名 一、选择题 1、是一种限制存取位置的线性表,元素的存取必须服从先进先出的规则。 A.顺序表B.链表C.栈D.队列 2、是一种限制存取位置的线性表,元素的存取必须服从先进后出的规则。 A.顺序表B.链表C.栈D.队列 3、与顺序表相比,链表不具有的特点是。 A.能够分散存储数据,无需连续内存空间 B.插入和删除无需移动数据 C.能够根据下标随机访问 D.只要内存足够,没有最大长度的限制 4、如果通过new运算符动态分配失败,返回结果是。 A.-1 B.0 C.1D.不确定 5、实现深复制中,不是必须自定义的。 A.构造函数B.复制构造函数 C.析构函数D.复制赋值操作符函数 6、分析下列代码是否存在问题,选择合适的选项:。 int main(void) { int *p = new int [10]; p = new int [10]; delete [] p; p = NULL; return 0; } A.没有问题 B.有内存泄漏 C.存在空悬指针 D.存在重复释放同一空间 7、通过new运算符动态分配的对象,存储于内存中的。 A.全局变量与静态变量区 B.代码区 C.栈区 D.堆区 8、下列函数中,可以是虚函数。 A.构造函数 B.析构函数 C.静态成员函数 D.友元函数 9、关于通过new运算符动态创建的对象数组,下列判断中是错误的。 A. 动态创建的对象数组只能调用默认构造函数 B. 动态创建的对象数组必须调用delete []动态撤销 C. 动态创建的对象数组的大小必须是常数或常变量 D. 动态创建的对象数组没有数组名 10、顺序表不具有的特点是 A. 元素的存储地址连续 B. 存储空间根据需要动态开辟,不会溢出 C. 可以直接随机访问元素 D. 插入和删除元素的时间开销与位置有关 11、假设一个对象Ob1的数据成员是指向动态对象的指针,如果采用浅复制的方式复制该对象得到对象Ob2,那么在析构对象Ob1和对象Ob2时会的问题。 A. 有重复释放 B. 没有 C. 内存泄漏 D. 动态分配失败 12、假设对5个元素A、B、C、D、E进行压栈或出栈的操作,压栈的先后顺序是ABCDE,则出栈的先后顺序不可能是。 A. ABCDE B. EDCBA C. EDBCA D. BCADE 13、假设对4个元素A、B、C、D、E进行压栈或出栈的操作,压栈的先后顺序是ABCD,则出栈的先后顺序不可能是。 A. ABCD B. DCBA C. BCAD D. DCAB 14、通过new运算符动态创建的对象的存放在中。 A. 代码区 B. 栈区 C. 自由存储区 D. 全局数据区 15、链表不具有的特点是。 A. 元素的存储地址可以不连续 B. 存储空间根据需要动态开辟,不会溢出 C. 可以直接随机访问元素 D. 插入和删除元素的时间开销与位置无关 16、有关内存分配和释放的说法,下面当中错误的是 A.new运算符的结果只能赋值给指针变量 B.动态创建的对象数组必须调用delete []动态撤销 C.用new分配的空间位置是在内存的栈区 D.动态创建的对象数组没有数组名 17、关于栈,下列哪项不是基本操作 A.删除栈顶元素 B.删除栈底元素 C.判断栈是否为空 D.把栈置空 18、关于链表,说法错误的是

计算机操作系统内存分配实验报告记录

计算机操作系统内存分配实验报告记录

————————————————————————————————作者:————————————————————————————————日期:

一、实验目的 熟悉主存的分配与回收。理解在不同的存储管理方式下,如何实现主存空间的分配与回收。掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。 二、实验内容和要求 主存的分配和回收的实现是与主存储器的管理方式有关的。所谓分配,就是解决多道作业或多进程如何共享主存空间的问题。所谓回收,就是当作业运行完成时将作业或进程所占的主存空间归还给系统。 可变分区管理是指在处理作业过程中建立分区,使分区大小正好适合作业的需求,并且分区个数是可以调整的。当要装入一个作业时,根据作业需要的主存量查看是否有足够的空闲空间,若有,则按需要量分割一个分区分配给该作业;若无,则作业不能装入,作业等待。随着作业的装入、完成,主存空间被分成许多大大小小的分区,有的分区被作业占用,而有的分区是空闲的。 实验要求使用可变分区存储管理方式,分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行,分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。同时,要求设计一个实用友好的用户界面,并显示分配与回收的过程。同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。 三、实验主要仪器设备和材料 实验环境 硬件环境:PC或兼容机 软件环境:VC++ 6.0 四、实验原理及设计分析 某系统采用可变分区存储管理,在系统运行当然开始,假设初始状态下,可用的内存空间为640KB,存储器区被分为操作系统分区(40KB)和可给用户的空间区(600KB)。 (作业1 申请130KB、作业2 申请60KB、作业3 申请100KB 、作业2 释放 60KB 、作业4 申请 200KB、作业3释放100KB、作业1 释放130KB 、作业5申请140KB 、作业6申请60KB 、作业7申请50KB) 当作业1进入内存后,分给作业1(130KB),随着作业1、2、3的进入,分别分配60KB、100KB,经过一段时间的运行后,作业2运行完毕,释放所占内存。此时,作业4进入系统,要求分配200KB内存。作业3、1运行完毕,释放所占内存。此时又有作业5申请140KB,作业6申请60KB,作业7申请50KB。为它们进行主存分配和回收。 1、采用可变分区存储管理,使用空闲分区链实现主存分配和回收。 空闲分区链:使用链指针把所有的空闲分区链成一条链,为了实现对空闲分区的分配和链接,在每个分区的起始部分设置状态位、分区的大小和链接各个分区的前向指针,由状态位指示该分区是否分配出去了;同时,在分区尾部还设置有一后向指针,用来链接后面的分区;分区中间部分是用来存放作业的空闲内存空间,当该分区分配出去后,状态位就由“0”置为“1”。 设置一个内存空闲分区链,内存空间分区通过空闲分区链来管理,在进行内存分配时,系统优先使用空闲低端的空间。 设计一个空闲分区说明链,设计一个某时刻主存空间占用情况表,作为主存当前使用基础。初始化空间区和已分配区说明链的值,设计作业申请队列以及作业完成后释放顺序,实现主存的分配和回收。要求每次分配和回收后显示出空闲内存分区链的情况。把空闲区说明

操作系统:进程调度实验报告

设计性实验报告 一、实验目的 1.在Linux下用C语言编程模拟优先级进程调度算法和时间片轮转进程调度算法。 2.为了清楚地观察每个进程的调度过程,每次调度程序应将各个进程的情况显示出来。 二、总体设计(设计原理、设计方案及流程等) 1、优先级进程调度算法 采用动态优先级进程调度算法,其基本思想是每次调度总是把处理机分配给优先级最高的进程,同时在运行过程中进程的优先级随着执行或等待的时间而降低或增加。 在该实验中每个进程用一个进程控制块( PCB)表示。进程控制块包含如下信息:进程号,进程名、优先数、需要运行时间、已用CPU时间、进程状态。进程号,名字,优先数,运行的时间,事先人为地指定。每个进程的状态可以是就绪,执行,阻塞或完成4种状态之一。 就绪进程获得 CPU后都只能运行一个时间片。用已占用CPU时间加1来表示。就绪队列中的进程在等待一个时间片后,优先级增1。如果运行一个时间片后,进程的已占用 CPU时间已达到所需要的运行时间,则撤消该进程,如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间,也就是进程还需要继续运行,此时将进程的优先级减1,然后把它插入就绪队列等待CPU。 2、时间片轮转调度算法 采用简单时间片轮转调度算法,其基本思想是:所有就绪进程按 FCFS排成一个队列,总是把处理机分配给队首的进程,各进程占用CPU的时间片相同。如果运行进程用完它的时间片后还未完成,就把它送回到就绪队列的末尾,把处理机重新分配给队首的进程。直至所有的进程运行完毕。 三、实验步骤(包括主要步骤、代码分析等) 1.打开linux虚拟机,用vim编辑器打开代码进行修改和调整。用gcc编译器进行编译编译运行首先运行优先级算法,如图所示:

操作系统实验内存分配

精心整理西安邮电大学 (计算机学院) 课内实验报告 1. (1 (2 (3 原因,写出实验报告。 2.实验要求: 1)掌握内存分配FF,BF,WF策略及实现的思路; 2)掌握内存回收过程及实现思路; 3)参考本程序思路,实现内存的申请、释放的管理程序,调试运行,总结程序设计中出现的问题并找出原因,写出实验报告。

3.实验过程: 创建进程: 删除其中几个进程:(默认以ff首次适应算法方式排列) Bf最佳适应算法排列方式: wf最差匹配算法排列方式: 4.实验心得: 明 实验中没有用到循环首次适应算法,但是对其他三种的描述还是很详细,总的来说,从实验中还是学到了很多。 5.程序源代码: #include #include #include #include

#define PROCESS_NAME_LEN 32 //进程名长度 #define MIN_SLICE 10 //最小碎片的大小#define DEFAULT_MEM_SIZE 1024 //内存大小 #define DEFAULT_MEM_START 0 //起始位置 /*内存分配算法*/ #define MA_FF 1 #define MA_BF 2 #define MA_WF 3 /*描述每一个空闲块的数据结构*/ struct free_block_type { }; /* /* { }; /* /* void display_menu(); int set_mem_size(); void set_algorithm(); void rearrange(int algorithm); int rearrange_WF(); int rearrange_BF(); int rearrange_FF(); int new_process(); int allocate_mem(struct allocated_block *ab);

操作系统实验 磁盘调度算法

操作系统 实验报告 哈尔滨工程大学 计算机科学与技术学院

第六讲磁盘调度算法 一、实验概述 1. 实验名称 磁盘调度算法 2. 实验目的 (1)通过学习EOS 实现磁盘调度算法的机制,掌握磁盘调度算法执行的条件和时机; (2)观察 EOS 实现的FCFS、SSTF和 SCAN磁盘调度算法,了解常用的磁盘调度算法; (3)编写 CSCAN和 N-Step-SCAN磁盘调度算法,加深对各种扫描算法的理解。 3. 实验类型 验证性+设计性实验 4. 实验内容 (1)验证先来先服务(FCFS)磁盘调度算法; (2)验证最短寻道时间优先(SSTF)磁盘调度算法; (3)验证SSTF算法造成的线程“饥饿”现象; (4)验证扫描(SCAN)磁盘调度算法; (5)改写SCAN算法。 二、实验环境 在OS Lab实验环境的基础上,利用EOS操作系统,由汇编语言及C语言编写代码,对需要的项目进行生成、调试、查看和修改,并通过EOS应用程序使内核从源代码变为可以在虚拟机上使用。 三、实验过程 1. 设计思路和流程图 (1)改写SCAN算法 在已有 SCAN 算法源代码的基础上进行改写,要求不再使用双重循环,而是只遍历一次请求队列中的请求,就可以选中下一个要处理的请求。算法流程图如下图所示。 图 3.1.1 SCAN算法IopDiskSchedule函数流程图(2)编写循环扫描(CSCAN)磁盘调度算法 在已经完成的SCAN算法源代码的基础上进行改写,不再使用全局变量ScanInside 确定磁头移动的方向,而是规定磁头只能从外向内移动。当磁头移动到最内的被访问磁道时,磁头立即移动到最外的被访问磁道,即将最大磁道号紧接着最小磁道号构成循环,进行扫描。算法流程图如下图所示。

计算机操作系统内存分配实验报告

一、实验目的 熟悉主存的分配与回收。理解在不同的存储管理方式下.如何实现主存空间的分配与回收。掌握动态分区分配方式中的数据结构和分配算法及动态分区存储管理方式及其实现过程。 二、实验内容和要求 主存的分配和回收的实现是与主存储器的管理方式有关的。所谓分配.就是解决多道作业或多进程如何共享主存空间的问题。所谓回收.就是当作业运行完成时将作业或进程所占的主存空间归还给系统。 可变分区管理是指在处理作业过程中建立分区.使分区大小正好适合作业的需求.并且分区个数是可以调整的。当要装入一个作业时.根据作业需要的主存量查看是否有足够的空闲空间.若有.则按需要量分割一个分区分配给该作业;若无.则作业不能装入.作业等待。随着作业的装入、完成.主存空间被分成许多大大小小的分区.有的分区被作业占用.而有的分区是空闲的。 实验要求使用可变分区存储管理方式.分区分配中所用的数据结构采用空闲分区表和空闲分区链来进行.分区分配中所用的算法采用首次适应算法、最佳适应算法、最差适应算法三种算法来实现主存的分配与回收。同时.要求设计一个实用友好的用户界面.并显示分配与回收的过程。同时要求设计一个实用友好的用户界面,并显示分配与回收的过程。 三、实验主要仪器设备和材料 实验环境 硬件环境:PC或兼容机 软件环境:VC++ 6.0 四、实验原理及设计分析 某系统采用可变分区存储管理.在系统运行当然开始.假设初始状态下.可用的内存空间为640KB.存储器区被分为操作系统分区(40KB)和可给用户的空间区(600KB)。 (作业1 申请130KB、作业2 申请60KB、作业3 申请100KB 、作业2 释放 60KB 、作业4 申请 200KB、作业3释放100KB、作业1 释放130KB 、作业5申请140KB 、作业6申请60KB 、作业7申请50KB) 当作业1进入内存后.分给作业1(130KB).随着作业1、2、3的进入.分别分配60KB、100KB.经过一段时间的运行后.作业2运行完毕.释放所占内存。此时.作业4进入系统.要求分配200KB内存。作业3、1运行完毕.释放所占内存。此时又有作业5申请140KB.作业6申请60KB.作业7申请50KB。为它们进行主存分配和回收。 1、采用可变分区存储管理.使用空闲分区链实现主存分配和回收。 空闲分区链:使用链指针把所有的空闲分区链成一条链.为了实现对空闲分区的分配和链接.在每个分区的起始部分设置状态位、分区的大小和链接各个分区的前向指针.由状态位指示该分区是否分配出去了;同时.在分区尾部还设置有一后向指针.用来链接后面的分区;分区中间部分是用来存放作业的空闲内存空间.当该分区分配出去后.状态位就由“0”置为“1”。 设置一个内存空闲分区链.内存空间分区通过空闲分区链来管理.在进行内存分配时.系统优先使用空闲低端的空间。 设计一个空闲分区说明链.设计一个某时刻主存空间占用情况表.作为主存当前使用基础。初始化空间区和已分配区说明链的值.设计作业申请队列以及作业完成后释放顺序.实现主存的分配和回收。要求每次分配和回收后显示出空闲内存分区链的情况。把空闲区说明链的变化情况以及各作业的申请、释放情况显示打印出来。

相关主题
文本预览
相关文档 最新文档