操作系统实验191.docx

上传人:b****6 文档编号:7496011 上传时间:2023-01-24 格式:DOCX 页数:20 大小:48.41KB
下载 相关 举报
操作系统实验191.docx_第1页
第1页 / 共20页
操作系统实验191.docx_第2页
第2页 / 共20页
操作系统实验191.docx_第3页
第3页 / 共20页
操作系统实验191.docx_第4页
第4页 / 共20页
操作系统实验191.docx_第5页
第5页 / 共20页
点击查看更多>>
下载资源
资源描述

操作系统实验191.docx

《操作系统实验191.docx》由会员分享,可在线阅读,更多相关《操作系统实验191.docx(20页珍藏版)》请在冰豆网上搜索。

操作系统实验191.docx

操作系统实验191

 

实验指导书

班级:

姓名:

学号

 

序言

计算机操作系统是计算机专业及其相关专业的核心专业课程,是计算机科学及其相关技术的重要部分,学好操作系统的原理并会应用其中学习的原理与方法可以是学习者大大提高各类软件设计的质量与水平,也可以懂得如何提高系统效率一起资源的利用率。

为了培养学生的时间动手能力,帮助学习很体会与验证学习的知识,特设计此实验体系。

实验共计需要30与学时,课程规模限制,集中安排16学时,其余需求学生可以课下完成,或者在教师的指导下有选择地完成实验。

实验报告要求:

1.提供各个实验程序的流程图,并填入实验报告中;

2.实验报告附上运行结果图的截图;

3.对实验的结果进行分析,写出自己的分析结果;

4.实验的源代码需要打包交到班级刻盘保存;个人文件的命名以个人的姓名+学号命名;班级的以班级编号命名。

5.需要程序可视性要好,要有试验程序证明作品的正确性。

6.所有的实验报告采用A4打印,字体字号采用模版规定。

7.源程序要加注释,要有测试数据及结果。

8.每个实验的报告要另起一页。

 

实验一进程同步和互斥

 

一、实验目的

1.掌握临界资源、临界区概念及并发进程互斥、同步访问原理。

2.学会使用高级语言进行多线程编程的方法。

3.掌握利用VC++或Java语言线程库实现线程的互斥、条件竞争,并编码实现P、V操作,利用P、V操作实现两个并发线程对有界临界区的同步访问。

4.通过该实验,学生可在源代码级完成进程同步互斥方案的分析、功能设计、编程实现,控制进程间的同步、互斥关系。

二、实验要求

1.知识基础:

学生应在完成进程和线程及调度等章节的学习后进行。

2.开发环境与工具:

硬件平台——个人计算机。

软件平台-Windows操作系统,vc++语言或Java语言开发环境。

3.运用高级语言VC++或Java语言线程库及多线程编程技术进行设计实现。

三、实验内容

1.实现临界资源、临界区、进程或线程的定义与创建。

2.利用两个并发运行的进程,实现互斥算法和有界缓冲区同步算法。

四、实验方案指导

该实验方案由以下几个关键设计项目组成:

1.并发访问出错

即设计一个共享资源,创建两个并发线程,二者并发访问该共享资源。

当没有采用同步算法设计时,线程所要完成的某些操作会丢失。

2.互斥锁

并发线程使用线程库提供的互斥锁,对共享资源进行访问。

3.软件方法

设计并编程实现计数信号量、P操作函数、V操作函数,并发线程通过调用P,V操作函数实现线程的互斥。

4.同步访问多缓冲区

利用上面的软件方法完成P,V操作可实现两个线程对多缓冲区的同步访问。

五、实验方案实现范例

以下是对该项目中包含的部分设计功能的实现方法、实现过程、技术手段的描述,供参考。

1.模拟线程并发运行。

假设我们使用POSIX线程库,而POSIX并没有真正提供线程间的并发运行需求。

我们设计的系统应支持符合RR调度策略的并发线程,每个线程运行一段时间后自动挂起,另一个线程开始运行。

这样一个进程内所有线程以不确定的速度并发执行。

2.模拟一个竞争条件——全局变量。

创建两个线程tl和t2,父线程主函数main()定义两个全局变量accntl和accnt2,每个变量表示一个银行账户,初始化为0。

每个线程模拟一个银行事务:

将一定数额的资金从一个账户转到另一个账户。

每个线程读入一个随机值,代表资金数额,在一个账户上做减法,在另一个账户上做加法,用两个变量记录两个账户的收支情况。

良性情况下收支应平衡,即两个全局变量之和应为0。

下面是每个线程的代码:

counter=0;

do{

tmp1=accnt1;

tmp2=accnt2;

r=random();

accnt1=tmp1+r;

accnt2=tmp2-r;

counter++;

}while(accnt1+accnt2==0);

printf(”%d”,counter);

=============================================================

两个线程运行的代码相同,只要各自代码不被交叉执行,两个收支余额之和就应一直为0,如果线程被交叉执行,某个线程可能会读入一个旧的accntl值和一个新的accnt2值,或者相反,这样会导致某个值的丢失。

当这种情况出现时,线程停止运行,并把出现情况的位置Counter的值)打印出来。

3.模拟一个竞争条件——共享文件。

主线程创建两个共享文件fl和f2,每个文件包含一个当前银行账户。

线程使用随机数对文件进行读/写,方式同上。

注意:

文件在读/写过程中不要加互斥访问锁,避免出现不会出现交叉访问的情况。

4.测试出现一个竞争条件的时间。

我们的编程环境中,一般无法支持线程的RR调度,必须编程实现两个线程间在两个赋值语句之间插入以下代码:

在指定区间(比如0到1)生成一个随机数,小于一个极限值(如0.1),调用线程自动挂起函数jield(),自动放弃CPU,另一运行,于是导致一个数据更新的丢失。

5.互斥锁。

POSIX线程库提供一个二值信号量,称为MUTEX,它可以加锁或解锁。

如果已被另一个线程加上锁的MUTEX加锁,就会引发该线程被阻塞,MUTEX解锁时唤醒它。

使用这些原语,很容易实现互斥进入CS(临界区)。

进入CS区时加锁,离开CS区时解锁。

系统负责阻塞或唤醒线程。

6.用软件方法实现互斥访问临界区。

用标准编程语言设置变量的值,用线程“忙等待”实现互斥访问CS。

设计两线程部分代码如下:

=============================================================

intcl=0,c2=0,will_wait;

p1:

while(l){

cl=l;

will_wait=l;

while(c2&&(will_wait==1));/*忙等待*/

csl;

cl=0;programl;

}

p2:

while(l){

c2=1;

will_wait=2;

while(cl&&(will_wait==2);/*忙等待*/

cs2;

c2=0;program2;

}

=============================================================

该软件方法使用三个变量cl,c2,will_wait,解决两个线程的同步问题。

两个线程分别将c1和c2设置为1,表示自己试图进入临界区,并将will_wait分别设置为1和2,以消除任何竞争条件。

通过“忙等待”循环实现线程的阻塞。

当线程退出CS区时,分别将变量c1和c2设置为0。

我们可以比较互斥锁和软件方法这两种解决方法的效率。

可以通过重复相同的循环次数,测量各自的执行时间,尽量减少可能的外部干扰,重复测试几次,并计算平均值。

以下部分由学生填写:

1.程序流程图

2.实验结果

3.结果分析

实验二进程及其资源管理

 

一、实验目的

1.理解资源共享与互斥特性以及操作系统管理资源的基本方法。

2.学会使用高级语言进行多线程编程的方法。

3.掌握利用VC++或Java线程库实现一个管理器,用来实现操作系统对进程及其资源的管理功能。

4.通过该实验,学生可在源代码级完成进程及其资源管理方案的分析、功能设计、编程实现,控制进程间的同步、互斥关系。

二、实验要求

1.知识基础:

学生应在完成对进程和线程、调度、死锁等章节的学习后进行。

2.开发环境与工具:

硬件平台——个人计算机。

软件平台——Windows操作系统,根据需要,任选安装VC++语言、java语言或C语言开发环境。

三、实验内容

1.开发一个函数,建立进程控制块和资源控制块结构,并实现相关数据结构的初始化。

2.开发一系列操作,由进程调用这些操作,达到控制进程申请或释放各种资源的目的。

四、实验方案指导

该实验方案由以下几个关键设计项目组成:

1.进程数据结构表示。

2.资源数据结构表示。

3.进程对资源的操作。

4.调度程序。

5.用户功能shell界面。

五、实验方案实现范例

以下是对该项目中包含的设计功能的实现方法、实现过程、技术手段的描述,供参考。

1.进程数据结构表示。

使用结构类型设计实现进程PCB表,它包含以下成员:

①进程ID——进程的唯一标识,供其他进程引用该进程;

②内存——是一个指针链表,它在创建进程时已申请完毕,可用链表实现;

③其他资源——指除去内存之外的所有资源;

④进程状态——包括两个数据类型,一个是状态码,另一个是状态队列链表指针;

⑤生成树——包括两个数据类型,本进程的父进程和本进程的子进程;

⑥优先级——供进程调度程序使用,用来确定下一个运行进程,可以设定为静态整数。

2.资源数据结构。

每个资源都用一个称为资源控制块的数据结构表示。

使用结构类型设计实现资源控制块RCB。

资源控制块包括以下字段成员:

①RID-资源的唯一标识,由进程引用;

②资源状态——空闲/已分配;

③等待队列——是被本资源阻塞的进程链表,本资源正被其他所有资源都设定为静态数据,系统启动时初始化。

3.进程管理及进程对资源的操作。

进程操作及进程状态转换归纳如下:

①进程创建——(无)→就绪;

②申请资源——运行→阻塞;

③资源释放——阻塞→就绪;

④删除进程——(任何状态)→(无);

5.调度程序——就绪→运行或运行→就绪。

具体实现步骤如下:

(1)根据上述数据结构,用高级语言设计相应函数,分别实现创建进程、删除进程、挂起进程、唤醒进程等功能。

(2)设计一个函数,实现调度程序,在每个进程操作执行完毕后,自动调用执行。

(3)实现两个资源操作:

申请资源和释放资源。

相关参考算法如下:

=============================================================

request(RID)/*申请资源算法*/

{r=get_RCB(RID);/*获取资源控制块首地址*/

if(r->status==’free’){/*资源可用*/

r->status=’allocated’;/*分配给调用进程,*/

insert(self->other_resources,r);}/*插入一个RCB指针指向进程资源链表;*/

else{/*资源不可用*/

self->status.type=’blocked’;/*记录阻塞*/

self->status.list=r;/*指向所请求资源的RCB*/

.remove(RL,self);/*将进程从就绪队列中删除*/

insert(r->waiting_list,self);}/*插入资源等待队列*/

scheduler();/*调度程序运行选择下一个运行进程*/

release(RID)/*释放资源算法*/

{r=get_RCB(RID);/*获取资源控制块首地址*/

remove(self->other_resource,r);/*从进程资源链表中删除该资源*/

if(waiting_list==NULL)r->status=’free’;/*等待队列为空,置资源状态为空闲*/

else{/*等待队列不为空*/

remove(r->waiting_list,q);/*从等待队列中移出一个进程q*/

q->status.type=’ready’;/*将进程q的状态设为就绪*/

q->status.list=RL;/*进程q的状态指针指向就绪队列*/

insert(RL,q);}/*进程q插入就绪队列*/

scheduler();/*调度程序运行选择下一个运行进程*/

=============================================================

4.调度程序。

调度策略采用固定优先级和可剥夺优先级调度算法。

即调度程序必须维护n个不同优先级的就绪队列,各就绪队列可为空,也可包含多个进程。

0级进程优先级最低,n-l级进程优先级最高。

创建进程时就赋予了固定的优先级,并在进程的生存期内保持不变。

当新进程创建或阻塞进程被唤醒时,它就被插入同级的就绪队列中。

调度程序按“先来先服务”和优先级“从高到低”的方式处理就绪队列。

即从最高优先级的非空就绪队列的队首选择一个进程进入运行态。

这样的调度策略很容易导致"饥饿",进程出现。

因为对进程q来说,只有当优先级高于自己的所有进程都运行完毕,或都进入阻塞状态时,它才能得到运行权。

为了简化调度程序,我们假定系统中至少有一个进程处于就绪态。

为确保这一点,设计一个特殊进程init,该进程在系统初始化时自动创建,并赋予最低优先级0级。

init进程有两个作用:

充当闲逛进程,该进程运行时不申请任何资源,以免被阻塞;作为第一个被创建的进程,它没有父进程,可创建比自己优先级高的其他进程。

所以init进程是进程生成树的根进程。

采用优先级策略的调度程序的常见结构知下所示:

=============================================================

scheduler()

{找出最高优先级进程p;

If(self->prioritypriority)||self->status.type!

=’running’||self=nil)

preempt(p,self);/*调度进程p,替换当前进程self*/

}

============================================================

每当任一进程的操作执行完毕,必须执行进程调度程序,它是当前运行进程的一部分。

进程调用该函数,后者决定该进程是继续执行还是被其他进程剥夺运行权。

作出判断的依据是:

是否存在高优先级进程p,如果存在,p将剥夺self的运行权。

当前进程的运行权被剥夺的情况有以下两种:

①当前进程刚刚完成release(操作,由此被唤醒进程的优先级可能高于当前进程。

②当前进程刚刚完成create()操作,新创建进程的优先级可能高于当前进程。

在以下两种情况下,新挑选的进程必须剥夺当前进程的运行权:

①当前进程刚刚完成reques()操作,并且申请的资源timeout则当前进程的状态就改为“阻塞”;或者由于分时运行进程的需要,调度程序被一个timeout操作调用运行。

在timeout操作中当前进程的状态改为“就绪”。

在上述情况中,当前进程的状态都不是“运行”。

所以当前进程必须停止运行,此时就绪队列中最高优先级的进程p得到执行。

②当进程刚刚完成destroy操作,进程自己删除自身,它的PCB表不再存在。

此时调度程序被执行,从就绪队列中选出最高优先级的进程p,并令其执行。

剥夺操作包括以下工作:

将选中的最高优先级进程p的状态改为“运行"。

如果当前进程依然存在且没有阻塞,则将其状态改为“就绪”,以便随后能得到执行。

最后,进行上下文切换,保留当前CPU的各个寄存器值,放入PCB表。

装入中选进程p的寄存器值。

本实现方案没有对实际的CPU进行访问来保存或恢复寄存器的值,因此上下文切换的任务只是将正在运行进程的名字显示在终端屏幕上。

从这一点可以认为,用户终端屏幕开始扮演当前运行进程功能的角色。

5.用户shell界面。

为RCB试和演示管理器的CPU能,本方案设计开发一个shell界面,它可以重复接受终端输入的命令,唤醒管理器执行相应的功能,并在屏幕上显示结果。

使用上述系统,终端就能展示当前进程。

只要输入一个命令,就中断当前进程序的执行,shell界面调用进程资源管理器中的函数F,并传递终端输入的参数。

该函数执行后将改变PCB、RCB及其他数据结构中的信息。

当调度程序执行时,决定下一个要运行的进程,并改变其状态值。

保存当前进程的CPU各寄存器值(虚拟CPU),然后恢复中选进程的值。

调度程序将系统状态信息显示在屏幕上,提示下一步操作。

特别地,它始终提示正在运行的进程是什么,即终端和键盘正在为哪个进程服务。

另外,函数F也可能返回一个错误码,shell也将它显示在屏幕上。

shell命令的语法格式规定如下:

命令名参数

例如,执行命令行“crA1”时将调用对应的管理器函数create(A,1),即创建一个名为A、优先级为1的进程。

同理,命令“rqR”将调用函数request(R)执行。

以下显示说明shell界面的交互内容(假定进程A的优先级为1,并且正在运行)。

由“*”开始的行视为shell的输崮结果。

提示符“>”后面是提示用户输入的命令。

……

*processAisrunning

>crB2

*processBisrunning

>crC1

*processBisrunning

>reqR1

*processBisblocked;processAisrunning

……

6.进程及资源管理器的升级版。

可对上述基本型进程功能资源管理器进行功能扩展,使管理器能够处理时钟到时中断和I/O处理完成中断。

(1)相对时钟到时中断。

假设系统提供一个硬件时钟。

周期性产生一个时钟到时中断。

引发调用函数timeout()的执行。

(2)110处理完成中断。

使用名为IO的资源表示所有的I/O设备。

该资源的RCB由以下两部分组成:

IO

Waiting_list

(3)扩展shell。

显示当前运行进程,并添加一个系统调用request_100。

终端也能表示硬件,用户能够模拟两种类型的中断:

时钟到时、I/O完成处理。

为了实现以上功能,必须添加新的shell命令,调用以下三个系统调用:

request_IO(),IO_competion,timeout()。

以下部分由学生填写:

1.程序流程图

2.实验结果

3.结果分析

 

实验三存储管理

 

一、实验目的

1.掌握内存管理的基本功能和分区法内存分配的基本原理。

2.学会Linux(或者windows)操作系统下使用c语言函数和系统调用进行编程的方法。

3.利用c语言设计实现分区法内存分配算法。

4.验证无虚存的存储管理机制。

二、实验要求

1.学生应完成如下章节的学习:

进程和线程、调度、存储管理。

2.安装Linux操作系统(无条件时可以用其他操作系统平台),使用c语言编程,调用相关系统调用进行设计实现。

三、实验内容

1.创建空闲存储管理表和模拟内存。

2.设计并实现一个内存分配程序,分配策略可以分别采用最先适应算法、最佳适应算法和最坏适应算法等,并评价不同分配算法的优劣。

3.提供一个用户界面,利用它用户可输入不同的分配策略。

4.进程向内存管理程序发出申请、释放指定数量的内存请求,内存管理程序调用对应函数,响应请求。

四、实验方案指导

该实验方案由以下几个关键设计项目组成。

1.设计实现一个空闲分区表。

2.设计实现模拟内存。

考虑实现的便利,本方案不访问真正的内存。

定义一个字符数组charmm[mem_size]或使用Linux系统调用mm=malloc(mem_size),用来模拟内存。

利用指针对模拟内存进行访问。

3.设计一组管理物理内存空间的函数。

用户接口由以下三个函数组成:

void*mm_request(intn)

申请n个字节的内存空间。

如申请成功,则返回所分配空间的首地址;如不能满足申请,则返回空值。

voidmm_release(void*p)

释放先前申请的内存。

如果释放的内存与空闲区相邻,则合并为一个大空闲区;如果与空闲区不相邻,则成为一个单独的空闲区。

void*mm_init(intmem_size)

内存初始化。

返回mm指针指向的空闲区。

4.设计实现不同策略的内存分配程序。

对于采用不同分配策略的内存管理程序,从以下两个方面进行调度程序性能的比对:

内存利用率以及找到一个合适的分配空间所需查找的步骤。

设置一个模拟实验。

分别构建一个随机生成的请求与释放队列。

释放队列中的操作总是得到满足,队列总为空;请求队列的操作能否被满足,取决于空闲区能否满足申请的空间大小。

若不能满足,则该操作在队列中等待相应释放操作唤醒。

请求队列采用FIFO管理,以避免饥饿现象的发生。

内存管理程序应对内存初始化,随机设定内存空间的占有、空闲情况,随机设定申请和释放的操作队列。

调用释放操作开始运行,调用申请操作,如能满足,则分配空间,否则等待释放操作唤醒。

下面给出一个模拟内存管理的程序框架(伪码形式)。

可对性能数据指标进行统计。

=============================================================

for(i=0;i

do{/*循环调用请求操作,直到请求不成功*/

getsizenofnextrequest;/*设定请求空间大小*/

mm_request(n);/*调用请求操作*/

}while(requestsuccessful);/*请求成功,循环继续*/

recordmemoryutilization;/*统计内存使用率*/

selectblockptoberelease;/*释放某空间p*/

release(p);/*调用释放操作*/

=============================================================

以上程序由主循环控制固定次数的模拟步骤。

每次循环,程序完成如下处理步骤:

内循环尽可能多地满足内存请求,请求内存大小值随机生成。

一旦请求失败,挂起内存管理程序,直至释放操作被执行。

此时进行系统内存利用率的统计、计算,随机挑选一个内存分配空间完成释放操作。

本次主循环执行完毕,开始下一次循环。

需要在程序中完成以下设计:

确定请求分配空间大小,统计性能数据,选择一个内存区释放。

以下部分由学生填写:

1.程序流程图

2.实验结果

3.结果分析

 

实验四页面置换算法

 

一、实验目的

1.掌握内存管理基本功能和请求分页式管理的基本原理以及页面置换算法。

2.学会在Linux操作系统下使用C函数和系统调用的编程方法。

3.掌握利用C语言设计实现不同置换策略的页面置换算法。

4.验证虚存存储管理机制及其性能。

对于生成的引用串,计算、比对不同页面置换算

法的缺页率。

二、实验要求

1.学生应完成如下章节的学习:

进程和线程、调度、存储管理。

2.安装Linux操作系统,使用C语言编程,利用相关系统调用实现设计。

三、实验内容

1.创建空闲存储管理表、模拟内存、页表等。

2.提供一个用户界面,用户利用它可输入不同的页面置换策略和其他附加参数。

3.运行置

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 基础医学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1