本实验的目的是使学生熟悉1—2种操作系统的界面,在熟练使用机器的基础上,能了解各种操作命令和系统调用在系统中的大致工作过程。也就是通过操作系统的外部特征,逐步深入到操作系统的内部实质内容中去。
在某种操作系统的环境下建立、修改、运行、打印源程序和结果,最后撤消一个完整的程序。
提示:可按下述步骤进行
1.建立工作路径
mkdir zhou
新建目录
dir
显示当前目录下的所有文件信息
2.编写源文件
Javac Homework.java
java Homework
Java源代码
import java.awt.Choice;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.Border;
public class Homework {
public static void main(String[] args) {
new MyFrame("周大哥的购物车").load();
}
}
class MyFrame extends JFrame {
JButton b1;
JButton b2;
JButton b3;
JButton b4;
JPanel p1;
JPanel p2;
JPanel p3;
Vector
Vector
JList j2;
JList j1;
MyFrame(String name) {
// this.setBackground(Color.BLUE);
this.setTitle(name);
// this.setIconImage(new );
b1 = new JButton(">>");
// b1.setContentAreaFilled(false);
b1.setBorder(BorderFactory.createRaisedBevelBorder());
b2 = new JButton(">");
b2.setBorder(BorderFactory.createRaisedBevelBorder());
b3 = new JButton("<<");
b3.setBorder(BorderFactory.createRaisedBevelBorder());
b4 = new JButton("<");
b4.setBorder(BorderFactory.createRaisedBevelBorder());
p1 = new JPanel();
p1.setBackground(Color.PINK);
//p1.setPreferredSize(new Dimension(300, 800));
b2.addMouseListener(new Mon1());
b4.addMouseListener(new Mon1());
b1.addMouseListener(new Mon2());
b3.addMouseListener(new Mon2());
// 中间的面板设置4行1列
p2 = new JPanel(new GridLayout(4, 1, 0, 20));
p2.setBackground(Color.red);
p3 = new JPanel();
p3.setBackground(Color.PINK);
p3.setBounds(100, 100, 400, 500);
vRight = new Vector
vRight.add("书");
vRight.add("笔");
vRight.add("橡皮");
vRight.add("眼镜");
vRight.add("手机");
vLeft = new Vector
vLeft.add("羽绒服");
vLeft.add("裤子");
vLeft.add("衬衣");
vLeft.add("运动鞋");
vLeft.add("背包");
vLeft.add("球拍");
j1 = new JList(vLeft);
//j1.setPreferredSize(new Dimension(80,10 ));
j1.setFont(new Font("宋体", Font.BOLD + Font.ITALIC, 30));
j1.setSelectionBackground(Color.yellow);
j2 = new JList(vRight);
j2.setFont(new Font("宋体", Font.BOLD + Font.ITALIC, 30));
j2.setSelectionBackground(Color.yellow);
//j2.setPreferredSize(new Dimension(100, 8));
}
void load() {
this.setLayout(new FlowLayout(FlowLayout.CENTER, 50, 50));
j1.add(b1);
j1.setVisibleRowCount(10);
p1.add(new JScrollPane(j1));
add(p1);
// 在面板內添加按鈕
p2.add(b1);
p2.add(b2);
p2.add(b3);
p2.add(b4);
add(p2);
// p3.add(t2);
j2.setVisibleRowCount(10);
p3.add(new JScrollPane(j2));
add(p3);
pack();
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLocationRelativeTo(null);
}
class Mon2 implements MouseListener {
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
JButton button = (JButton) e.getSource();
if (button.getText().equals(">>")) {
vRight.addAll(vLeft);
vLeft.clear();
// System.out.println("我执行了");
} else {
vLeft.addAll(vRight);
vRight.clear();
}
j1.updateUI();
j2.updateUI();
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}
class Mon1 implements MouseListener {
@Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
// TODO Auto-generated method stub
JButton t = (JButton) e.getSource();
// 向右移动
if (t.getText().equals(">")) {
int num[] = j1.getSelectedIndices();
if (num.length == 0 || vLeft.size() == 0) {
JOptionPane.showMessageDialog(null, "亲,请选择选项后移动");
} else if (num.length >= 1) {
Vector
for (int i : num) {
// if((vLeft.get(i))!=null)
temp.add(vLeft.get(i));
}
for (String i : temp) {
vLeft.remove(i);
vRight.add(i);
}
}
} // 向左移动
else if (t.getText().equals("<")) {
int num[] = j2.getSelectedIndices();
Vector
if (num.length == 0 || vRight.size() == 0) {
JOptionPane.showMessageDialog(null, "亲,请选择好后移动");
} else {
for (int i : num) {
// if((vRight.get(i))!=null)
temp.add(vRight.get(i));
}
for (String aa : temp) {
vRight.remove(aa);
vLeft.add(aa);
}
}
}
j2.updateUI();
j1.updateUI();
j1.setSelectedIndex(0);
j2.setSelectedIndex(0);
}
@Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
@Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
}
}
实践是检验真理的唯一标准,通过对目前市场上的windows和ubuntu操作系统的认识,让我对操作系统有了新的理解和应用。Ubuntu系统有以下几方面的优点:
1.高效的文件管理系统,一般情况下不需要碎片整理
2.产生的系统垃圾很少,系统不会随着使用时间的增多而越来越卡
3.拷贝文件速度快,Win10达到5M/S,Ubuntu达到20M/S
4.系统安全稳定,漏洞修复快,极少中病毒
5.权限管理很严格,避免用户误操作
6.DIY界面,改善用户体验,自由度高(对UI有追求的同学可尽情折腾)
7.强大的命令行,基本上所有操作可在上面执行(瞬间逼格升几个Lev)
8.无软件捆绑行为,桌面无广告弹窗行为
9.无盗版系统这一说法,开源免费正版
而Windows10的优点如下:
1.软件多,软件多,软件多(重要的事情说三遍)
2.操作方式对电脑小白友好,上手快 。
3.使用普及率高,同事间协助合作方便。.
4.Win10针对Modern应用进行优化,提升用户体验(界面简洁,运行流畅,去除少用功能,保留核心有用的功能,安装包体积小) 。
5.支持大量驱动,充分发挥硬件性能。
在实际开发中,应当按照自己的项目需求来恰当选择。文字/命令行界面虽然没有图形界面美观,但操作响应速度快,执行稳定,不容易出错。
进程是操作系统最重要的概念之一,进程调度是操作系统的主要内容,本实验要求学生独立地用高级语言编写一个进程调度程序,调度算法可任意选择或自行设计,本实验可使学生加深对进程调度和各种调度算法的理解。
为了便于处理,程序中进程的运行时间以时间片为单位计算。各进程的优先数或轮转时间片数、以及进程需要运行的时间片数,均由伪随机数发生器产生。
进程控制块结构如表2-1所示:
表2-1PCB
进程标识符 |
链指针 |
优先数/轮转时间片数 |
占用CPU时间片数 |
进程所需时间片数 |
进程状态 |
进程控制块链结构如图2-1所示:
RUN HEAD TAIL
1 |
┇ |
R |
3 |
┇ |
W |
5 |
┇ |
W |
W |
0 |
┇ |
2 |
…
图2-1 进程控制块链结构
其中:RUN—当前运行进程指针;
HEAD—进程就绪链链首指针;
TAIL—进程就绪链链尾指针。
2. 算法与框图程序框图如图2-2所示。
priority |
是 |
输入调度算法alog |
开始 |
alog=priority/round robin? |
生成并按优先数大小排列进程控制块链 |
进程时间片数为0? |
从链首取一个进程投入运行 |
生成并按进入次序 排列进程控制块链 |
链首进程投入运行 |
时间片到,进程时间片 数减1,优先数减3 |
运行进程退出,排到进程链尾部 |
撤消该进程 |
链首进程投入运行 |
时间片到,进程时间片数 减1,占用CPU时间加1 |
优先数大于链首进程? |
进程时间片数为0? |
撤消该进程 |
运行进程退出,按优先数插入进程链 |
从链首取一个进程投入运行 |
结束 |
结束 |
进程队列空? |
进程队列空? |
是 |
是 |
是 |
否 |
否 |
否 |
否 |
否 |
是 |
round robin |
占用处理机时间片到? |
否 |
是 |
图2-2 进程调度框图
(1)优先数法。 进程就绪链按优先数大小从大到小排列,链首进程首先投入运行。每过一个时间片,运行进程所需运行的时间片数减1,说明它已运行了一个时间片,优先数也减3。理由是该进程如果在一个时间片中完成不了,优先级应降低一级。接着比较现行进程和就绪链链首进程的优先数,如果仍是现行进程高或者相同,就让现行进程继续运行,否则,调度就绪链链首进程投入运行。原运行进程再按其优先数大小插入就绪链,且改变它们对应的进程状态,直至所有进程都运行完各自的时间片数。
(2)简单轮转法。 进程就绪链按各进程进入的先后次序排列,链首进程首先投入运行。进程每次占用处理机的轮转时间按其重要程度登入进程控制块中的轮转时间片数记录项(相应于优先数法的优先数记录项位置)。每过一个时间片,运行进程占用处理机的时间片数加1,然后比较占用处理机的时间片数是否与该进程的轮转时间片数相等,若相等说明已到达轮转时间,应将现运行进程排到就绪链末尾,调度链首进程占用处理机,且改变它们的进程状态,直至所有进程完成各自的时间片。
#include
#include
#include
using namespace std;
int n;
class PCB
{
public:
int priorityNumber;//进程优先数
int occupy;//进程运行CPU时间
int pieceOftime;//轮转时间片
int need;//还需要时间
int Counter;
string processName;//进程名
string state;//进程状态
PCB * next;
};
PCB * run = NULL;
PCB * ready = NULL;
PCB * finish = NULL;
PCB * tial = ready;
void Dtime(int t);
void Prinft(int a)
{
if(a==1)
{
cout<<" 进程"<<"\t"<<"优先数"<<"\t"<<"还需要时间"<<"\t"<<"已运行时间"<<"\t"<<"状态:"< } else cout<<" 进程"<<"\t"<<"已运行时间"<<"\t"<<"还需要时间"<<"\t"<<"计数器"<<"\t"<<"时间片"<<"\t"<<"状态"< } void Prinft(int b,PCB * p) { if(b==1) { cout< } else cout< } void display(int c) { PCB *p; if(run!=NULL) Prinft(c,run); //Dtime(2); p=ready; while(p!=NULL) { Prinft(c,p); p=p->next; } //Dtime(2); p=finish; while(p!=NULL) { Prinft(c,p); p=p->next; } } void insert(PCB *p)//插入就绪队列按Pri大小 { PCB *S1,*S2; if(ready==NULL) { p->next = NULL; ready = p; } else { S1 = ready; S2 = S1; while(S1!=NULL) { if(S1->priorityNumber >= p->priorityNumber) { S2 = S1; S1 = S1->next; } else break; } if(S2->priorityNumber >= p->priorityNumber) { S2->next = p; p->next = S1; } else { p->next = ready; ready = p; } } } bool CTProcessOfPri() { PCB * Node; cout <<"请输入创建进程的数目:"< cin >>n; for(int j = 0;j < n; j++) { Node = new PCB; if(Node==NULL) return false; else { cout <<"亲,请输入进程的名称,进程需CPU时间例如:process 45"< cin >>Node->processName>>Node->need; Node->occupy = 0; Node->state ="就绪态"; Node->priorityNumber =Node->need; cout <<"进程"< } insert(Node); } return true; } void priorityNumberority(int i) { run = ready; ready = ready->next; run->state = "运行态"; Prinft(i); while(run!=NULL) { run->occupy=run->occupy+1; run->need=run->need-1; run->priorityNumber=run->priorityNumber-1; if(run->need==0) { run->state = "完成"; run->next = finish; finish = run; run=NULL; if(ready!=NULL) { run = ready; run->state = "运行态"; ready = ready->next; } } else if((ready!=NULL)&&(run->priorityNumber { run->state="就绪态"; insert(run); run = ready; run->state = "运行态"; ready = ready->next; } display(i); } } void queue(PCB *p) { if(ready==NULL) { p->next = NULL; ready = p; tial = p; } else { tial->next = p; tial = p; p->next = NULL; } } bool CTProcessOfRuntime() { PCB * Node; int m; cout <<"请输入创建进程的数目:"< cin >>n; cout <<"输入时间片:"< cin >>m; for(int j = 0;j < n; j++) { Node = new PCB; if(Node==NULL) return false; else { cout <<"亲,请输入进程的名称,进程需CPU时间例如:process 8"< cin >>Node->processName>>Node->need; Node->occupy = 0; Node->state ="就绪态"; Node->Counter = 0; Node->pieceOftime = m; cout <<"进程"< } queue(Node); } return true; } void Runtime(int c) { run = ready; ready = ready->next; run->state = "运行态"; Prinft(c); while(run!=NULL) { run->occupy=run->occupy+1; run->need=run->need-1; run->Counter = run->Counter + 1; if(run->need==0) { run->state = "完成"; run->next = finish; finish = run; run = NULL; if(ready!=NULL) { run = ready; ready = ready->next; } } else if(run->Counter == run->pieceOftime) { run->Counter = 0; run->state = "就绪态"; queue(run); run=NULL; if(ready!=NULL) { run = ready; run->state = "运行态"; ready = ready->next; } } display(c); } } int main() { string i=""; cout <<" 功能选项:"< cout <<"q键退出"< cout <<"输入p选择优先数调度算法"< cout <<"输入x选择循环时间片轮转算法"< cin >>i; if(i=="p") { CTProcessOfPri(); priorityNumberority(1); } else if(i=="x"){ CTProcessOfRuntime(); Runtime(2); } else if(i=="q"){ return 0; } } void Dtime(int t) { time_t current_time; time_t start_time; time(&start_time); do { time(& current_time); }while((current_time-start_time) } /* 1.优先数调度算法 5 a 3 b 2 c 10 d 4 e 8 2.循环时间片轮转算法 5 10 a 3 b 2 c 10 d 4 e 8 */ 优先数调度 进程 优先数 还需要时间 已运行时间 状态: c 9 9 1 运行态 e 8 8 0 就绪态 d 4 4 0 就绪态 a 3 3 0 就绪态 b 2 2 0 就绪态 c 8 8 2 运行态 e 8 8 0 就绪态 d 4 4 0 就绪态 a 3 3 0 就绪态 b 2 2 0 就绪态 e 8 8 0 运行态 c 7 7 3 就绪态 d 4 4 0 就绪态 a 3 3 0 就绪态 b 2 2 0 就绪态 e 7 7 1 运行态 c 7 7 3 就绪态 d 4 4 0 就绪态 a 3 3 0 就绪态 b 2 2 0 就绪态 c 7 7 3 运行态 e 6 6 2 就绪态 d 4 4 0 就绪态 a 3 3 0 就绪态 b 2 2 0 就绪态 c 6 6 4 运行态 e 6 6 2 就绪态 d 4 4 0 就绪态 a 3 3 0 就绪态 b 2 2 0 就绪态 e 6 6 2 运行态 c 5 5 5 就绪态 d 4 4 0 就绪态 a 3 3 0 就绪态 b 2 2 0 就绪态 e 5 5 3 运行态 c 5 5 5 就绪态 d 4 4 0 就绪态 a 3 3 0 就绪态 b 2 2 0 就绪态 c 5 5 5 运行态 d 4 4 0 就绪态 e 4 4 4 就绪态 a 3 3 0 就绪态 b 2 2 0 就绪态 c 4 4 6 运行态 d 4 4 0 就绪态 e 4 4 4 就绪态 a 3 3 0 就绪态 b 2 2 0 就绪态 d 4 4 0 运行态 e 4 4 4 就绪态 a 3 3 0 就绪态 c 3 3 7 就绪态 b 2 2 0 就绪态 e 4 4 4 运行态 a 3 3 0 就绪态 c 3 3 7 就绪态 d 3 3 1 就绪态 b 2 2 0 就绪态 e 3 3 5 运行态 a 3 3 0 就绪态 c 3 3 7 就绪态 d 3 3 1 就绪态 b 2 2 0 就绪态 a 3 3 0 运行态 c 3 3 7 就绪态 d 3 3 1 就绪态 b 2 2 0 就绪态 e 2 2 6 就绪态 c 3 3 7 运行态 d 3 3 1 就绪态 b 2 2 0 就绪态 e 2 2 6 就绪态 a 2 2 1 就绪态 d 3 3 1 运行态 b 2 2 0 就绪态 e 2 2 6 就绪态 a 2 2 1 就绪态 c 2 2 8 就绪态 d 2 2 2 运行态 b 2 2 0 就绪态 e 2 2 6 就绪态 a 2 2 1 就绪态 c 2 2 8 就绪态 b 2 2 0 运行态 e 2 2 6 就绪态 a 2 2 1 就绪态 c 2 2 8 就绪态 d 1 1 3 就绪态 e 2 2 6 运行态 a 2 2 1 就绪态 c 2 2 8 就绪态 d 1 1 3 就绪态 b 1 1 1 就绪态 a 2 2 1 运行态 c 2 2 8 就绪态 d 1 1 3 就绪态 b 1 1 1 就绪态 e 1 1 7 就绪态 c 2 2 8 运行态 d 1 1 3 就绪态 b 1 1 1 就绪态 e 1 1 7 就绪态 a 1 1 2 就绪态 c 1 1 9 运行态 d 1 1 3 就绪态 b 1 1 1 就绪态 e 1 1 7 就绪态 a 1 1 2 就绪态 d 1 1 3 运行态 b 1 1 1 就绪态 e 1 1 7 就绪态 a 1 1 2 就绪态 c 0 0 10 完成 b 1 1 1 运行态 e 1 1 7 就绪态 a 1 1 2 就绪态 d 0 0 4 完成 c 0 0 10 完成 e 1 1 7 运行态 a 1 1 2 就绪态 b 0 0 2 完成 d 0 0 4 完成 c 0 0 10 完成 a 1 1 2 运行态 e 0 0 8 完成 b 0 0 2 完成 d 0 0 4 完成 c 0 0 10 完成 a 0 0 3 完成 e 0 0 8 完成 b 0 0 2 完成 d 0 0 4 完成 c 0 0 10 完成 循环时间片轮转 进程 已运行时间 还需要时间 计数器 时间片 状态 a 1 2 1 10 运行态 b 0 2 0 10 就绪态 c 0 10 0 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 a 2 1 2 10 运行态 b 0 2 0 10 就绪态 c 0 10 0 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 b 0 2 0 10 就绪态 c 0 10 0 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 a 3 0 3 10 完成 b 1 1 1 10 就绪态 c 0 10 0 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 a 3 0 3 10 完成 c 0 10 0 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 b 2 0 2 10 完成 a 3 0 3 10 完成 c 1 9 1 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 b 2 0 2 10 完成 a 3 0 3 10 完成 c 2 8 2 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 b 2 0 2 10 完成 a 3 0 3 10 完成 c 3 7 3 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 b 2 0 2 10 完成 a 3 0 3 10 完成 c 4 6 4 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 b 2 0 2 10 完成 a 3 0 3 10 完成 c 5 5 5 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 b 2 0 2 10 完成 a 3 0 3 10 完成 c 6 4 6 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 b 2 0 2 10 完成 a 3 0 3 10 完成 c 7 3 7 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 b 2 0 2 10 完成 a 3 0 3 10 完成 c 8 2 8 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 b 2 0 2 10 完成 a 3 0 3 10 完成 c 9 1 9 10 就绪态 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 b 2 0 2 10 完成 a 3 0 3 10 完成 d 0 4 0 10 就绪态 e 0 8 0 10 就绪态 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 d 1 3 1 10 就绪态 e 0 8 0 10 就绪态 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 d 2 2 2 10 就绪态 e 0 8 0 10 就绪态 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 d 3 1 3 10 就绪态 e 0 8 0 10 就绪态 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 e 0 8 0 10 就绪态 d 4 0 4 10 完成 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 e 1 7 1 10 就绪态 d 4 0 4 10 完成 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 e 2 6 2 10 就绪态 d 4 0 4 10 完成 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 e 3 5 3 10 就绪态 d 4 0 4 10 完成 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 e 4 4 4 10 就绪态 d 4 0 4 10 完成 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 e 5 3 5 10 就绪态 d 4 0 4 10 完成 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 e 6 2 6 10 就绪态 d 4 0 4 10 完成 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 e 7 1 7 10 就绪态 d 4 0 4 10 完成 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 e 8 0 8 10 完成 d 4 0 4 10 完成 c 10 0 10 10 完成 b 2 0 2 10 完成 a 3 0 3 10 完成 -------------------------------- Process exited after 14.68 seconds with return value 0 请按任意键继续. . . 纸上得来终觉浅,总得要实践一把才印象深刻,对上课所学知识才能真正理解消化。为了能使程序并发的执行,并且可以对并发执行的程序加以控制,引入进程。为了使参与并发执行的每个程序都能独立运行,为每个进程配置一个进程控制块PCB,用PCB来描述进程的基本情况和活动过程,进而控制和管理进程。这样由程序段、相关的数据段和PCB三部分构成了进程实体。进程是程序的一次执行。 进程是一个程序及其数据在处理上顺序执行时所发生的的活动。 进程是具有独立功能的程序在一个数据集合上运行的过程它是系统进行资源分配的独立单位。进程是一个资源的拥有者,如果频繁的进行创建撤销切换会造成很大的时空开销。所以,引入线程,将线程作为调度和分派的基本单位,进程作为资源分配的独立单位。各种调度算法之间的灵活使用对于操作系统的快速、稳定地执行具有重要的意义。 存储管理的主要功能之一是合理地分配主存空间。请求页式管理是一种常用的虚拟存储管理技术。 本实验的目的是通过请求页式存储管理中页面置换算法的模拟设计,来了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。 模拟页式虚拟存储管理中硬件的地址转换和缺页中断的处理过程,并用先进先出调度算法(FIFO)处理缺页中断。 表3-1 页表格式 页 号 标 志 主存块号 修改标志 磁盘上的位置 P[0],P[1],…,P[m-1] 它们的初值为P[0]∶=0,P[1]∶=1,…,P[m-1]∶= m-1 用一指针k指示当要装入新页时应调出的页在数组的位置,k的初值为“0”。 j∶= P[k] j页的修改标志=1? 输出“OUTj” P[k]∶=L k∶=(k+1) mod m 修改页表 输出“IN L” 取一条指令 开始 页标志=1? 输出绝对地址 取一条指令 输出“﹡页号” 取指令中访问的页号=>L 查页表 形成绝对地址 置L页修改标志”1” 结束 是”存”指令? 有后继指令? 否(产生缺页中断) 是 否 否 否 是 是 模拟硬件 地址转换 模拟FIFO页面调度 是 图3-1 地址转换和FIFO页面调度流程 当产生缺页中断后,操作系统总是选择P[k]所指出的页面调出,然后执行 P[k]∶=要装入的新页页号 k∶=(k+1)mod m 在实验中不必实际地启动磁盘执行调出一页和装入一页的工作,而用输出“OUT调出的页号”和“IN要装入的新页页号”来模拟一次调出和装入的过程。模拟程序的流程见图3-1。 表3-2 作业的页表 页号 标志 主存块号 修改标志 在磁盘上的位置 0 1 5 0 011 1 1 8 0 012 2 1 9 0 013 3 1 1 0 021 4 0 0 022 5 0 0 023 6 0 0 121 如果该作业依次执行的指令序列如表3-3所示。 表3-3 作业依次执行的指令序列 操作 页号 页内地址 操作 页号 页内地址 + 0 070 移位 4 053 + 1 050 + 5 023 × 2 015 存 1 037 存 3 021 取 2 078 取 0 056 + 4 001 - 6 040 存 6 084 依次执行上述的指令序列来调试你所设计的程序(仅模拟指令的执行,不必考虑指令序列中具体操作的执行) #include #include #include #define NUM 7 #define WNUM 12 using namespace std; struct pagetable { int num;// 页号 int flag;// 标志 int block;// 主存块号 int modify;// 修改标志 int location;// 磁盘上的位置 }; // 主存块号是-1 说明该页没有调入主存 struct pagetable page[NUM]={{0,1,5,0,010},{1,1,8,0,012},{2,1,9,0,013},{3,1,1,0,021},{4,0,-1,0,022},{5,0, -1,0,023},{6,0,-1,0,121}}; struct work { char operation[10];// 操作 int pagenum;// 页号 int address;// 页内地址 }; struct work w[WNUM]={{"+",0,70},{"+",1,50},{"*",2,15},{" 存",3,21}, {" 取",0,56},{"-",6,40},{" 移位",4,53},{"+",5,23}, {" 存",1,37},{" 取",2,78},{"+",4,1},{" 存",6,84}}; int main() { int k=0;// 当要装入新页时应调出的页在数组的位置 int m=4;// 允许分配的最大块数 int curpage = 0;// 当前页号 int p[4] = {0,1,2,3};// 当前已在主存中的页面 int replace;// 替换页的页号 int tempflag; int tempmodify; long memoryaddress;// 物理地址(绝对地址) cout<<" 最后的结果是:"< printf("\n 操作\t页号\t页内地址 标志 绝对地址 修改页号 绝对地址 修改标志\n"); for(int i=0;i { curpage = w[i].pagenum; tempflag = page[curpage].flag; if(page[curpage].flag == 0) { replace = p[k]; p[k] = curpage; k=(k+1)%m; page[curpage].flag = 1; page[curpage].block = page[replace].block; tempmodify = page[replace].modify; page[replace].block = -1; page[replace].flag = 0; page[replace].modify = 0; } memoryaddress = 1024*page[curpage].block+w[i].address; if(!strcmp(w[i].operation," 存") || !strcmp(w[i].operation," 写")) page[curpage].modify=1; else page[curpage].modify=0; printf(" %s\t",w[i].operation); printf(" %d\t",w[i].pagenum); printf(" %d\t",w[i].address); printf(" %d\t",tempflag); if(tempflag==1) printf(" %d\t",memoryaddress); else printf(" *%d\t",w[i].pagenum); if(tempflag==1) printf(" \t"); else printf(" %d->%d\t",w[i].pagenum,replace); printf(" %d\t",memoryaddress); printf(" %d\t",page[curpage].modify); printf("\n"); } } 实验结果截图如下: 输入为:表3-3 作业依次执行的指令序列 操作 页号 页内地址 操作 页号 页内地址 + 0 070 移位 4 053 + 1 050 + 5 023 × 2 015 存 1 037 存 3 021 取 2 078 取 0 056 + 4 001 - 6 040 存 6 084 C++编程可以模拟实现很多操作系统原理,通过一步步实现其中的原理,可以帮助更好地深入理解操作系统内部构造,将抽象的东西具体化。在实际运行过程,把有关作业的全部信息都装入主存储器后,作业执行时实际上不是同时使用全部信息的,有些部分运行一遍便再也不用,甚至有些部分在作业执行的整个过程中都不会被使用到(如错误处理部分)。进程在运行时不用的,或暂时不用的,或某种条件下才用的程序和数据,全部驻留于内存中是对宝贵的主存资源的一种浪费,大大降低了主存利用率。 于是,提出了这样的问题:作业提交时,先全部进入辅助存储器,作业投入运行时,能否不把作业的全部信息同时装入主存储器,而是将其中当前使用部分先装入主存储器,其余暂时不用的部分先存放在作为主存扩充的辅助存储器中,待用到这些信息时,再由系统自动把它们装入到主存储器中,这就是虚拟存储器的基本思路。这都是通过编程来解决操作系统中实际遇到的问题,对上课了解的知识能给予很好地扩充。 四、实验结果:
五、心得体会:
实验三 存储管理程序设计
一、目的和要求
二、提示
四、实验结果:
五、心得体会: