课程编号:B080000070
《操作系统》实验报告
姓名 |
| 学号 |
| |
班级 |
| 指导教师 |
| |
实验名称 | 《操作系统》实验 | |||
开设学期 | 2016-2017第二学期 | |||
开设时间 | 第11周——第18周 | |||
报告日期 | 2017年7月8日 | |||
评定成绩 |
| 评定人 |
| |
评定日期 |
|
东北大学软件学院
实验一 进程的同步与互斥
一、实验目的
(1)加深对进程概念的理解,明确进程和程序的区别。
(2)进一步认识并发执行的实质。
(3)分析进程竞争资源现象,学习解决进程互斥的方法。
二、预习内容
预习进程同步有关理论,包括进程的基本操作和经典的进程同步与互斥问题。
三、实验内容
1.生产者:规定生产总量,生产者一直等待消费者传来的缓冲区数据已空的信号,一旦接受到该信号,生产者便进入关键代码段,进行生产数据活动,生产过后从关键代码段出来,发出信号通知消费者取数据。
2.消费者:一直等待生产者传来数据已经生产的信号,一旦接收到该信号,消费者便进入关键代码段,取数据,取完数据后离开关键代码段,发信号通知生产者缓冲区已空,该进行数据生产。
四、流程图
分析:本实验要求利用PV操作实现解决生产者——消费者问题中的同步问 题。此问题描述的是一群生产者进程在生产产品并将这些产品提供给消费者进程去消费,在两者之间设置了一个具有n个缓冲区的缓冲池,生产者进程将它所生产的产品放入一个缓冲区,消费者进程可从缓冲区中取走产品去消费,但它们之间必须保持同步,即不允许消费者进程到一个空缓冲区去取产品,也不允许生产者进程向一个已装满且尚未取出的缓冲区中投放产品,并且生产者消费者互斥使用缓冲区。
流程图如下:
五、关键代码
1.生产者线程函数
unsigned int __stdcall ProducerThreadFun(PVOID pM)
{
for (int i = 1; i <= END_PRODUCE_NUMBER; i++)
{
//等待缓冲区为空
WaitForSingleObject(g_hEventBufferEmpty, INFINITE);
//互斥的访问缓冲区
EnterCriticalSection(&g_cs);
g_Buffer = i;
printf("生产者生产%d\n", i);
LeaveCriticalSection(&g_cs);
//通知缓冲区有新数据了
SetEvent(g_hEventBufferFull);
}
return 0;
}
//消费者线程函数
unsigned int __stdcall ConsumerThreadFun(PVOID pM)
{
volatile bool flag = true;
while (flag)
{
//等待缓冲区中有数据
WaitForSingleObject(g_hEventBufferFull, INFINITE);
//互斥的访问缓冲区
EnterCriticalSection(&g_cs);
printf(" 消费者消费%d\n", g_Buffer);
if (g_Buffer == END_PRODUCE_NUMBER)
flag = false;
LeaveCriticalSection(&g_cs);
//通知缓冲区已为空
SetEvent(g_hEventBufferEmpty);
Sleep(10); //some other work should to do
}
return 0;
}
六、实验结果
代码的运行结果如下:
六、思考题
(1)如何控制进程间的相互通信?
1.管道通信:管道是一种半双工的通信方式,数据只能单向流动,而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。
2.信号:信号量是一个计数器,可以用来控制多个进程对共享资源的访问。它常作为一种锁机制,防止某进程正在访问共享资源时,其他进程也访问该资源。因此,主要作为进程间以及同一进程内不同线程之间的同步手段。
3.消息队列:消息队列是消息的链接表。对消息队列有读权限的进程则可以从消息队列中读取信息。其基本思想是:根据”生产者-消费者”原理,利用内存中公用消息缓冲区实现进程之间的信息交换.内存中开辟了若干消息缓冲区,用以存放消息.每当一个进程向另一个进程发送消息时,便申请一个消息缓冲区,并把已准备好的消息送到缓冲区,然后把该消息缓冲区插入到接收进程的消息队列中,最后通知接收进程.接收进程收到发送里程发来的通知后,从本进程的消息队列中摘下一消息缓冲区,取出所需的信息,然后把消息缓冲区不定期给系统.系统负责管理公用消息缓冲区以及消息的传递.一个进程可以给若干个进程发送消息,反之,一个进程可以接收不同进程发来的消息.显然,进程中关于消息队列的操作是临界区.当发送进程正往接收进程的消息队列中添加一条消息时,接收进程不能同时从该消息队列中到出消息。
4.共享内存:依靠某种同步操作,如互斥锁和信号量等。
5.信号量:主要作为进程之间及同一种进程的不同线程之间得同步和互斥手段。
6.套接字:套解口也是一种进程间通信机制,与其他通信机制不同的是,它可用于不同及其间的进程通信。
(2)什么是进程的同步?什么是进程的互斥?分别有哪些实现方式?
互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
同步:是指在互斥的基础上,通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源。
关于同步与互斥的实现具有典型意义的方法是p、v操作。p、v操作是定义在信号量上的两个原语操作。信号量是表示资源的物理量,也是一个与队列有关的整形变量,用s表示。其值仅能由p,v操作原语来改变。当s<0时,其绝对值代表进入信号量执政队列的处于等待状态的进程数:当s>0时,其值代表系统中可用的资源数:当s=0是,表示所有资源都分配给了所有进程。系统利用信号量对进程控制和管理,及控制进程对临界资源或者公共变量的访问,以实现进程的同步与互斥。
实验二 处理机调度
一、实验目的
(1)加深对处理机调度的作用和工作原理的理解。
(2)进一步认识并发执行的实质。
二、预习内容
预习课本处理机调度有关内容,包括进程占用处理机的策略方法。
三、实验内容
1.首先定义数据结构,定义好进程的结构体模板
2.输入5个进程的名称、优先数、所需运行时间后对进程根据优先级排序
3.每次循环将优先权最高的程序的优先级和所需时间减1,cpu时间加1
4.当所有进程所需时间均为0时结束循环
四、流程图
五、关键代码
1.对进程优先级排序
pbcp p1, p2, p3, p4;
p4 = NULL;
while (p4 != pbca->p->p)
{
for (p1 = pbca; p1->p->p != p4; p1 = p1->p)
{
if ((p1->p->pri)<(p1->p->p->pri))
{
p2 = p1->p;
p3 = p1->p->p;
p1->p = p3;
p2->p = p3->p;
p3->p = p2;
}
}
p4 = p1->p;
}
2.循环执行对优先级最高的进程的相关操作
while (p1->time == 0)
p1 = p1->p;
if ((p1->time -= 1) == 0)
{
p1->cputime += 1;
p1->pri -= 1;
strcpy(p1->status, "finish");
sort(pbca);
}
else
{
strcpy(p1->status, "run");
p1->cputime += 1;
p1->pri -= 1;
//strcpy(p1->status, "run");
}
p2 = p1->p;
while (p2 != NULL)
{
if (p2->cputime != 0)
{
(p2->cputime) += 1;
}
p2 = p2->p;
}
printPbc(pbca);
五、实验结果(部分)
六、思考题
(1)处理机调度的目的?
合理快速的处理计算机软件硬件资源
(2)你实现优先权调度算法的思想?
运用链表,在每次对进程执行相关操作前对优先级队列进行排序,优先级高的排在队列前端。
(3)你采用时间片轮转法实现处理机调度的思想?
将时间以一个cpu时间为单位,每次循环代表一次cpu时间,每次对优先级最高的进程进行操作。
(4)比较效率如何?
每次cpu时间执行完后都要对所有进程进行优先权排序,浪费一定时间,但是每次都保证了执行当前优先级做高的进程。
实验三 存储管理
一、实验目的
(1)加深对存储管理的作用和工作原理的理解。
(2)进一步认识主存空间的分配和回收方法。
(3)进一步认识虚拟存储器的工作原理。
二、预习内容
预习课本存储管理有关内容,包括各种内存分配方法和利用分页式存储管理实现虚拟存储器策略方法。
三、实验内容
选择实现模拟分页式存储管理中硬件的地址转换和产生缺页中断以及用先进先出(FIFO)页面调度算法处理缺页中断。
实验3-1:
1.定义页表格式的结构体
2.定义指令格式结构体
3.初始化页表
4.执行指令的查找操作,判断缺页与否与是否越界。
实验3-2:
1.定义页表格式的结构体
2.定义指令格式结构体
3.初始化页表
4.执行指令的查找操作,判断缺页与否与是否越界。
5.弱缺页,利用FIFO算法进行页置换
四、关键代码
判断指令是否发生缺页或越界
if(flag==0&&p2[i].pagenum<7)//不在主存
{
printf("*pagenum=%d Page fault generated\n\n",p2[i].pagenum);
}
else if(p2[i].pagenum<7)
{
memaddress=p1[page].block*size+p2[i].address;
printf(" memaddress=block(%d)*size(%d)+address(%d);\n memaddress= %ld\n\n",
p1[page].block,size,p2[i].address,memaddress);
}
else
printf("page over! again\n");
2.如果要发生页置换,利用FIFO算法将最早进入的页置换掉:
if (pagelist[P[po]].dirty)
{
//将更新后的内容写回外存
pagelist[P[po]].dirty=0;
}
pagelist[P[po]].flag=0;//修改要调出的页标志
printf("调出 %ld 调入 %ld\n",P[po],p); //显示调出调入页面
pagelist[p].block=pagelist[P[po]].block;
pagelist[p].flag=1;//该页被调入内存
P[po]=p;
po=(po+1)%M;
五、实验结果
1.普通页查询:
2.FIFO
六、思考题
(1)先进先出页面调度算法的思想?
在即将发生页置换时,将最先到来的页置换出去。
(2)最近最少用(LRU)页面调度算法思想?
设块数为n,将最近的n-1个页保留,剩余的一个置换出去。
(3)比较两种调度算法的效率(哪种调度算法使产生缺页中断的次数少)?
LRU效率高于先进新出算法,页错误率低。
(4)分析在什么情况下采用哪种调度算法更有利?
当之后要来的页为现最早到来页时LRU好,当最近经常使用但将来不常使用的情况新进先出好。
实验四 文件系统
一、实验目的
(1)加深理解文件系统的内部功能及内部实现。
(2)进一步认识文件系统的作用。
二、预习内容
预习课本文件系统有关内容,包括文件和目录的创建和删除等基本原理。
三、实验内容
1.创建UDF、MDF结构体链表。
2.通过控制台输入初始化用户链表和用户文件列表。
3.实现各个查询以及更新功能。
4.进行创建删除打开等操作。
四、流程图
打开文件的流程图如下:
五、
删除的流程图如下:
六、实验结果
代码的测试结果如下:
首先进行初始化,也是注册的过程;
然后进行登陆验证和创建文件:
然后进行是删除操作:
五、思考题
(1)文件管理的思想?
根据不同单位计算机技术在现行文件和文档管理中应用情况,可以分为三种模式,一是现代文件和档案管理分别应用计算机技术模式;二是现行文件和档案管理综合应用技术模式;三是电子文件模式。要结合本单位的特点,采用相应的管理模式。
(2)目录管理的思想?
管理索引,操作索引,不直接对文件进行操作。