资源描述
^.
课程编号:B080000070
《操作系统》实验报告
姓名
班级
指导教师
石凯
实验名称
《操作系统》实验
开设学期
2016-2017第二学期
开设时间
第11周——第18周
报告日期
2017年7月3日
评定成绩
评定人
石凯
评定日期
2017年7月5日
东北大学软件学院
实验一 进程的同步与互斥
实验题目:
通过学习和分析基础例子程序,使用windows进程和线程编程(也可以采用Java 或Unix/Linux的POSIX线程编程)实现一个简单的生产者/消费者问题的程序。
关键代码:
import java.util.ArrayList;
public class Produce {
public Object object;
public ArrayList list;//用list存放生产之后的数据,最大容量为1
public Produce(Object object,ArrayList list ){
this.object = object;
this.list = list;
}
public void produce() {
synchronized (object) {
/*只有list为空时才会去进行生产操作*/
try {
while(!list.isEmpty()){
System.out.println("生产者"+Thread.currentThread().getName()+" waiting");
object.wait();
}
int value = 9999;
list.add(value);
System.out.println("生产者"+Thread.currentThread().getName()+" Runnable");
object.notifyAll();//然后去唤醒因object调用wait方法处于阻塞状态的线程
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
import java.util.ArrayList;
public class Consumer {
public Object object;
public ArrayList list;//用list存放生产之后的数据,最大容量为1
public Consumer(Object object,ArrayList list ){
this.object = object;
this.list = list;
}
public void consmer() {
synchronized (object) {
try {
/*只有list不为空时才会去进行消费操作*/
while(list.isEmpty()){
System.out.println("消费者"+Thread.currentThread().getName()+" waiting");
object.wait();
}
list.clear();
System.out.println("消费者"+Thread.currentThread().getName()+" Runnable");
object.notifyAll();//然后去唤醒因object调用wait方法处于阻塞状态的线程
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
实验结果:
思考题:
(1)如何控制进程间的相互通信?答:主要有:管道,信号,共享内存,消息队列
(2)什么是进程的同步?什么是进程的互斥?分别有哪些实现方式?
答:进程互斥是进程之间的间接制约关系。当一个进程进入临界区使用临界资源时,另一个进程必须等待。只有当使用临界资源的进程退出临界区后,这个进程才会解除阻塞状态。进程同步也是进程之间直接的制约关系,是为完成某种任务而建立的两个或多个线程,这个线程需要在某些位置上协调他们的工作次序而等待、传递信息所产生的制约关系。进程间的直接制约关系来源于他们之间的合作。可以利用信号量来实现进程的同步与互斥。实验二 处理机调度
实验题目:
设计一个按优先权调度算法实现处理器调度的程序
数据结构及符号说明:
typedef struct pb { //每个进程
char pname[5]; //进程的名字
char status[8]; //进程的状态
int time; //要求运行时间
int pri; //进程的优先权
int cputime; //cpu时间
struct pb *p; //队列结构,它的下一个。
}pbc, *pbcp;
流程设计:
关键代码:
void attemper(pbcp pbca) {
pbcp pItem = pbca->p;
pbcp pIterator = pbca->p;
while (pIterator!= NULL) {
if (pItem->pri <= pIterator->pri&&pIterator->time != 0) {
pItem = pIterator;
}
pIterator = pIterator->p;
}
if ((pItem->time -= 1) == 0) {
pItem->cputime += 1;
pItem->pri -= 1;
strcpy(pItem->status, "finish");
}
else {
strcpy(pItem->status, "run");
pItem->cputime += 1;
pItem->pri -= 1;
strcpy(pItem->status, "run");
}
pIterator = pbca->p;
while (pIterator != NULL) {
if (pIterator->cputime != 0&&pIterator!=pItem&&pIterator->time!=0) {
pIterator->cputime += 1;
strcpy(pIterator->status, "ready");
}
pIterator = pIterator->p;
}
printPbc(pbca);
}
运行结果:
思考题:
(1)处理机调度的目的?答:主要还是为了优化软件的运行。
(2)你实现优先权调度算法的思想?答:遍历一次,取出优先权最高的,判断该进程是否还要运行,要允许就运行它。
实验三 存储管理
实验题目:
模拟分页式存储管理中硬件的地址转换和产生缺页中断。
用先进先出(FIFO)页面调度算法处理缺页中断。
数据结构及符号说明:
int paper_table[7][5] //7乘5的页表
char *oper_char[12] //每次操作
int oper_table[12][2] //指令序列的单元号和操作存储
int fifo_table[4] // 先进先出表,记录那几个在内存中
int static count = 0; //记下哪个先来的
流程设计:
核心代码:
void scheduler(void)
{
int i, page, page_block, page_move;
for (i = 0; i<12; i++)
{
page = **(oper_table + i);
printf("-----------------%d--------------------\n", i);
if (*(*(paper_table + page) + 1) == 1) {//在页表中
page_block = *(*(paper_table + page) + 2);
page_move = *(*(oper_table + i) + 1);
printf("在内存中,块号:%d;偏移量:%d;物理地址:%d\n", page_block, page_move, page_block * 128 + page_move);
*(*(paper_table + count) + 4) = 1;//修改变为1
fifo_print();
}
else {
if (*(*(paper_table + fifo_table[count % 4]) + 4) == 1) {
printf("缺页中断,被替换的页号为:%d;页修改存入硬盘\n", fifo_table[count]);
*(*(paper_table + fifo_table[count % 4]) + 4) = 0;
}
else {
printf("缺页中断,被替换的页号为:%d;页被直接替换\n", fifo_table[count]);
}
*(*(paper_table + page) + 1) = 1;//移入内存,改变在内存中的标志为1
*(*(paper_table + fifo_table[count]) + 1) = 0;//改变在内存中的标志为0
*(*(paper_table + page) + 2) = *(*(paper_table + fifo_table[count]) + 2);//重置页表里的主存块号值
*(*(paper_table + fifo_table[count]) + 2) = 0;//重置页表里的主存块号值
fifo_table[count % 4] = *(*(oper_table + i) + 0);//更新fifo表
page_block = *(*(paper_table + page) + 2);
page_move = *(*(oper_table + i) + 1);
printf("换入内存成功,块号:%d;偏移量:%d;物理地址:%d;\n", page_block, page_move, page_block * 128 + page_move);
fifo_print();
count++;
count = count % 4;
}
printf("\n");
}
}
实验结果:
思考题:
(1)先进先出页面调度算法的思想?答:基本思想:先进入内存的页面先淘汰,后进入内存的后淘汰
(2)最近最少用(LRU)页面调度算法思想?答:基本思想:最近用的最少的最先淘汰。
(3)比较两种调度算法的效率(哪种调度算法使产生缺页中断的次数少)?
答:从作业题我感觉最近最少使用优于先进先出。
(4)分析在什么情况下采用哪种调度算法更有利?
答:如果页访问高度随机的话,不见得LRU好,LRU是根据最近最少使用的来决定哪个页表被替换,但过去很多时候不能代表未来。
实验四 文件系统
实验题目:
用高级语言编写和调试一个简单的文件系统,模拟文件管理的工作过程。
数据结构及符号说明:
struct TYPE_UFD //主文件目录
{
string File_Name; //文件名
bool Read; //是否可读可写可执行
bool Write;
bool Execute;
int Length_File; //文件长度
};
struct TYPE_MFD //用户文件目录
{
string User_Name; //用户名
TYPE_UFD *Pointer;
};
struct TYPE_AFD //打开文件目录,即运行文件目录
{
int File_ID; //文件ID
bool Read;
bool Write;
bool Execute;
int Pointer;
};
class TYPE_FILE_SYSTEM //文件系统类
{
public:
void Initial(void);
void Start(void);
private:
int _Number_Users; //用户数
int _Number_Files; //文件数
int _MaxNumber_Open_Files; //最大打开文件数
TYPE_MFD *_MFD;
TYPE_UFD *_UFD;
TYPE_AFD *_AFD;
};
流程设计:
关键代码:
void TYPE_FILE_SYSTEM::Start(void)
{
int User_ID;
int i, temp_int;
string temp;
char choice;
int Number_Open_Files;
string User_Name;
string Command;
TYPE_UFD *UFD;
do
{
do
{
cout << "已创建指令有:create delete open dir diropen write read logout shutdown \n\n";
cout << "请输入用户名:";
cin >> User_Name;
for (User_ID = 0; User_ID<_Number_Users; User_ID++)
{
if (_MFD[User_ID].User_Name == User_Name)
break;
}
if (User_ID == _Number_Users)
cout << "用户名错误,请再次输入 ." << endl;
} while (User_ID == _Number_Users);
cout << "欢迎登录 , " << User_Name << " !" << endl;
UFD = _MFD[User_ID].Pointer;
for (i = 0; i<_MaxNumber_Open_Files; i++)
{
_AFD[i].File_ID = -1;
}
Number_Open_Files = 0;
do
{
cout << "C:\\" << User_Name << ">";
cin >> Command;
if (Command == "dir")
{
cout << endl;
cout << "打开用户 " << User_Name << "的文件 " << endl;
cout << "\t" << "State\t" << "Length\t" << "File name" << endl;
for (i = 0; i<_Number_Files; i++)
{
if (UFD[i].Length_File != -1)
{
cout << "\t";
if (UFD[i].Read == true)
cout << "R";
else
cout << "-";
if (UFD[i].Write == true)
cout << "W";
else
cout << "-";
if (UFD[i].Execute == true)
cout << "E";
else
cout << "-";
cout << "\t";
cout << UFD[i].Length_File;
cout << "\t";
cout << UFD[i].File_Name << endl;
}
}
cout << endl;
}
else if (Command == "diropen")
{
cout << endl;
cout << "打开用户 " << User_Name << "的文件 " << endl;
cout << "\t" << "State\t" << "Open File name" << endl;
for (i = 0; i<_MaxNumber_Open_Files; i++)
{
if (_AFD[i].File_ID != -1)
{
cout << "\t";
if (_AFD[i].Read == true)
cout << "R";
else
cout << "-";
if (_AFD[i].Write == true)
cout << "W";
else
cout << "-";
if (_AFD[i].Execute == true)
cout << "E";
else
cout << "-";
cout << "\t";
cout << UFD[_AFD[i].File_ID].File_Name << endl;
}
}
cout << endl;
}
else if (Command == "create")
{
for (i = 0; i<_Number_Files; i++)
if (UFD[i].Length_File == -1)
break;
if (i == _Number_Files)
cout << "Error: 已有名为 " << _Number_Files << " 的文件." << endl;
else
{
cout << "请输入新文件信息:" << endl;
cout << "文件名 : ";
cin >> temp;
UFD[i].File_Name = temp;
cout << "文件权限 : ";
cout << "Read (y/n):";
do
{
choice = getch();
} while (choice != y && choice != n);
if (choice == y)
UFD[i].Read = true;
else
UFD[i].Read = false;
cout << endl;
cout << "Write (y/n):";
do
{
choice = getch();
} while (choice != y && choice != n);
if (choice == y)
UFD[i].Write = true;
else
UFD[i].Write = false;
cout << endl;
cout << "Execute (y/n):";
do
{
choice = getch();
} while (choice != y && choice != n);
if (choice == y)
UFD[i].Execute = true;
else
UFD[i].Execute = false;
cout << endl;
cout << "Length :";
cin >> temp_int;
if (temp_int > 0)
UFD[i].Length_File = temp_int;
cout << "新文件 " << UFD[i].File_Name << " 已建立!" << endl;
}
}
else if (Command == "delete")
{
cout << "请输入文件名 :";
cin >> temp;
for (i = 0; i<_Number_Files; i++)
if ((UFD[i].Length_File != -1) && (UFD[i].File_Name == temp))
break;
if (i == _Number_Files)
cout << "文件名错误,请再次输入 ." << endl;
else
{
UFD[i].Length_File = -1;
cout << "文件 " << UFD[i].File_Name << " 已删除 ." << endl;
}
}
else if (Command == "open")
{
if (Number_Open_Files == _MaxNumber_Open_Files)
cout << "Error: 你已经打开了 " << Number_Open_Files << " 文件." << endl;
else
{
cout << "请输入文件名:";
cin >> temp;
for (i = 0; i<_Number_Files; i++)
if ((UFD[i].Length_File != -1) && (UFD[i].File_Name == temp))
break;
if (i == _Number_Files)
cout << "文件名错误,请再次输入 ." << endl;
else
{
Number_Open_Files++;
for (temp_int = 0; temp_int<_MaxNumber_Open_Files; temp_int++)
if (_AFD[temp_int].File_ID == -1)
break;
_AFD[temp_int].File_ID = i;
_AFD[temp_int].Pointer = 0;
cout << "请定义打开方式 :" << endl;
if (UFD[i].Read == true)
{
cout << "Read (y/n):";
do
{
choice = getch();
} while (choice != y && choice != n);
if (choice == y)
_AFD[temp_int].Read = true;
else
_AFD[temp_int].Read = false;
cout << endl;
}
else
_AFD[temp_int].Read = false;
if (UFD[i].Write == true)
{
cout << "Write (y/n):";
do
{
choice = getch();
} while (choice != y && choice != n);
if (choice == y)
_AFD[temp_int].Write = true;
else
_AFD[temp_int].Write = false;
cout << endl;
}
else
_AFD[temp_int].Write = false;
if (UFD[i].Execute == true)
{
cout << "Execute (y/n):";
do
{
choice = getch();
} while (choice != y && choice != n);
if (choice == y)
_AFD[temp_int].Execute = true;
else
_AFD[temp_int].Execute = false;
cout << endl;
}
else
_AFD[temp_int].Execute;
cout << "文件 " << temp << " 已打开 ." << endl;
}
}
}
else if (Command == "logout")
{
cout << "再见 , " << User_Name << " !" << endl;
break;
}
else if (Command == "close")
{
cout << "请输入文件名 :";
cin >> temp;
for (i = 0; i<_Number_Files; i++)
if ((UFD[i].Length_File != -1) && (UFD[i].File_Name == temp))
break;
if (i == _Number_Files)
cout << "文件名错误,请再次输入 ." << endl;
else
{
for (temp_int = 0; temp_int<_MaxNumber_Open_Files; temp_int++)
if (_AFD[temp_int].File_ID == i)
break;
if (temp_int == _MaxNumber_Open_Files)
cout << "文件 " << temp << " 未打开 ." << endl;
else
{
_AFD[temp_int].File_ID = -1;
Number_Open_Files--;
cout << "文件 " << temp << " 已关闭 ." << endl;
}
}
}
else if (Command == "read")
{
cout << "请输入文件名 :";
cin >> temp;
for (i = 0; i<_Number_Files; i++)
if ((UFD[i].Length_File != -1) && (UFD[i].File_Name == temp))
break;
if (i == _Number_Files)
cout << "文件名错误,请再次输入 ." << endl;
else
{
for (temp_int = 0; temp_int<_MaxNumber_Open_Files; temp_int++)
if (_AFD[temp_int].File_ID == i)
break;
if (temp_int == _MaxNumber_Open_Files)
cout << "文件 " << temp << " 未打开 ." << endl;
else
{
if (_AFD[temp_int].Read == true)
cout << "文件 " << temp << " 成功读取." << endl;
else
cout << "Error: 文件打开模式错误 ." << endl;
}
}
}
else if (Command == "write")
{
cout << "请输入文件名 :";
cin >> temp;
for (i = 0; i<_Number_Files; i++)
if ((UFD[i].Length_File != -1) && (UFD[i].File_Name == temp))
break;
if (i == _Number_Files)
cout << "文件名错误,请再次输入 ." << endl;
else
{
for (temp_int = 0; temp_int<_MaxNumber_Open_Files; temp_int++)
if (_AFD[temp_int].File_ID == i)
break;
if (temp_int == _MaxNumber_Open_Files)
cout << "文件 " << temp << " 未打开 ." << endl;
else
{
if (_AFD[temp_int].Write == true)
cout << "文件 " << temp << " 成功写入." << endl;
else
cout << "Error: 文件打开模式错误 ." << endl;
}
}
}
else if (Command == "shutdown")
{
cout << "正在注销........" << endl;
cout << "再见 , " << User_Name << " !" << endl;
cout << "正在关机.........." << endl;
break;
}
else
{
cout << "指令错误,请再次输入 ." << endl;
}
} while (Command != "logout" && Command != "shutdown");
} while (Command != "shutdown");
}
实验结果:
评价表格
考核标准
得分
(1)正确理解和掌握实验所涉及的概念和原理(20%);
(2)按实验要求合理设计数据结构和程序结构(20%);
(3)运行结果正确(20%);
(4)认真记录实验数据,原理及实验结果分析准确(20%);
(5)实验过程中,具有严谨的学习态度和认真、踏实、一丝不苟的科学作风(10%);
(7)实验报告规范(10%)。
合计
展开阅读全文
温馨提示:
得力文库 - 分享文档赚钱的网站所有资源均是用户自行上传分享,仅供网友学习交流,未经上传用户书面授权,请勿作他用。
相关搜索