操作系统实验报告Word下载.docx

上传人:b****8 文档编号:22346006 上传时间:2023-02-03 格式:DOCX 页数:21 大小:160.71KB
下载 相关 举报
操作系统实验报告Word下载.docx_第1页
第1页 / 共21页
操作系统实验报告Word下载.docx_第2页
第2页 / 共21页
操作系统实验报告Word下载.docx_第3页
第3页 / 共21页
操作系统实验报告Word下载.docx_第4页
第4页 / 共21页
操作系统实验报告Word下载.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

操作系统实验报告Word下载.docx

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

操作系统实验报告Word下载.docx

//缓冲区是个循环队列

boolg_continue=true;

//控制程序结束

HANDLEg_hMutex;

//用于线程间的互斥

HANDLEg_hFullSemaphore;

//当缓冲区满时迫使生产者等待

HANDLEg_hEmptySemaphore;

//当缓冲区空时迫使消费者等待

DWORDWINAPIProducer(LPVOID);

//生产者线程

DWORDWINAPIConsumer(LPVOID);

//消费者线程

intmain()

{

//创建各个互斥信号

g_hMutex=CreateMutex(NULL,FALSE,NULL);

g_hFullSemaphore=CreateSemaphore(NULL,SIZE_OF_BUFFER-1,SIZE_OF_BUFFER-1,NULL);

g_hEmptySemaphore=CreateSemaphore(NULL,0,SIZE_OF_BUFFER-1,NULL);

//调整下面的数值,可以发现,当生产者个数多于消费者个数时,

//生产速度快,生产者经常等待消费者;

反之,消费者经常等待

constunsignedshortPRODUCERS_COUNT=3;

//生产者的个数

constunsignedshortCONSUMERS_COUNT=1;

//消费者的个数

//总的线程数

constunsignedshortTHREADS_COUNT=PRODUCERS_COUNT+CONSUMERS_COUNT;

HANDLEhThreads[PRODUCERS_COUNT];

//各线程的handle

DWORDproducerID[CONSUMERS_COUNT];

//生产者线程的标识符

DWORDconsumerID[THREADS_COUNT];

//消费者线程的标识符

//创建生产者线程

for(inti=0;

i<

PRODUCERS_COUNT;

++i){

hThreads[i]=CreateThread(NULL,0,Producer,NULL,0,&

producerID[i]);

if(hThreads[i]==NULL)return-1;

}

//创建消费者线程

CONSUMERS_COUNT;

hThreads[PRODUCERS_COUNT+i]=CreateThread(NULL,0,Consumer,NULL,0,&

consumerID[i]);

while(g_continue){

if(getchar()){//按回车后终止程序运行

g_continue=false;

return0;

}

//生产一个产品。

简单模拟了一下,仅输出新产品的ID号

voidProduce()

std:

:

cerr<

<

"

Producing"

<

++ProductID<

..."

;

Succeed"

endl;

//把新生产的产品放入缓冲区

voidAppend()

Appendingaproduct..."

g_buffer[in]=ProductID;

in=(in+1)%SIZE_OF_BUFFER;

//输出缓冲区当前的状态

SIZE_OF_BUFFER;

cout<

i<

"

g_buffer[i];

if(i==in)std:

--生产"

if(i==out)std:

--消费"

//从缓冲区中取出一个产品

voidTake()

Takingaproduct..."

ConsumeID=g_buffer[out];

out=(out+1)%SIZE_OF_BUFFER;

//消耗一个产品

voidConsume()

Consuming"

ConsumeID<

//生产者

DWORDWINAPIProducer(LPVOIDlpPara)

WaitForSingleObject(g_hFullSemaphore,INFINITE);

WaitForSingleObject(g_hMutex,INFINITE);

Produce();

Append();

Sleep(1500);

ReleaseMutex(g_hMutex);

ReleaseSemaphore(g_hEmptySemaphore,1,NULL);

//消费者

DWORDWINAPIConsumer(LPVOIDlpPara)

WaitForSingleObject(g_hEmptySemaphore,INFINITE);

Take();

Consume();

ReleaseSemaphore(g_hFullSemaphore,1,NULL);

五、实验总结

生产者消费者算法是一个经典的进程同步算法,我所采用的纪录型信号量解决的此问题。

算法的思想比较简单,但是实现起来不容易。

特别是要模拟两个进程,一个生产,一个消费比较困难。

为了解决此问题,我特地学习了Windows下使用C++如何创造线程,从而控制生产-消费的过程。

通过本实验,我更加深入地了解了生产者-消费者算法,同时也学会了如何应用信号量机制来同步进程。

实验二银行家算法

通过实验使学生进一步了解资源安全分配的算法。

基本能达到下列具体的目标:

1.理解死锁概念,以及死锁产生的必要条件。

2.理解银行家算法基本原理。

3.掌握一种资源和多种资源的银行家算法的设计与实现。

1.设计出管理的资源种类和数量 

2.设计出银行家算法的基本数据结构

3.设计出完成该资源的银行家算法 

4.设计出简单的进程创建、运行资源需求、结束的过程 

//银行家算法

#include<

iomanip>

#defineMAX_PROCEDURE_NUM5

#defineRESOURCE_TYPE_NUM1

usingnamespacestd;

classProcedure

public:

//private:

intRequest[RESOURCE_TYPE_NUM];

//public:

intSentReq(intj){returnRequest[j];

};

classBanker

intAvailable[RESOURCE_TYPE_NUM];

intmax[MAX_PROCEDURE_NUM][RESOURCE_TYPE_NUM];

intAllocation[MAX_PROCEDURE_NUM][RESOURCE_TYPE_NUM];

intNeed[MAX_PROCEDURE_NUM][RESOURCE_TYPE_NUM];

boolApplyResource(Procedure&

p,intProID);

//分配资源函数

boolSafetyCheck(intResourceNum);

//检测系统安全性函数

voidPrintTable();

//输出系统的资源分配情况

boolBanker:

ApplyResource(Procedure&

p,intProID)

for(intj=0;

j<

RESOURCE_TYPE_NUM;

j++)

{

if(p.SentReq(j)<

=Need[ProID][j])

{

if(p.SentReq(j)<

=Available[j])

{

intPreAvailable,PreAllocation,PreNeed;

PreAvailable=Available[j];

PreAllocation=Allocation[ProID][j];

PreNeed=Need[ProID][j];

//先暂存以前的值

Available[j]=Available[j]-p.SentReq(j);

Allocation[ProID][j]=Allocation[ProID][j]+p.SentReq(j);

Need[ProID][j]=Need[ProID][j]-p.SentReq(j);

if(!

SafetyCheck(j))//ifnot,rollback

{

Available[j]=PreAvailable;

Allocation[ProID][j]=PreAllocation;

Need[ProID][j]=PreNeed;

cout<

分配不安全!

}

elsecout<

分配成功!

}

else{cout<

资源不足!

returnfalse;

}

}

else{cout<

申请过大!

SafetyCheck(intResourceNum)

intwork[RESOURCE_TYPE_NUM];

//系统供给进程继续运行所需的各类资源数目

for(inti=0;

i++)work[i]=Available[i];

//算法开始时,work:

=Available

boolFinish[MAX_PROCEDURE_NUM];

//表示系统是否有足够的资源分配给进程,使之运行完成

MAX_PROCEDURE_NUM;

i++)Finish[i]=false;

//刚开始时初始化为false

i++)

if(Finish[i]==false&

&

Need[i][ResourceNum]<

=work[ResourceNum])

work[ResourceNum]=work[ResourceNum]+Allocation[i][ResourceNum];

Finish[i]=true;

i=0;

continue;

//一旦有新资源产生就重新扫描

i++)

if(Finish[i]==false)returnfalse;

//一旦有一个进程不能完成,返回false

returntrue;

//所有进程满足安全状态,返回true

voidBanker:

PrintTable()

cout.setf(ios:

internal);

cout.width(10);

cout<

Procedure"

cout.width(10*RESOURCE_TYPE_NUM);

Max"

cout.width(10*RESOURCE_TYPE_NUM);

Allo"

Need"

cout<

'

\n'

'

for(inta=0;

a<

3;

a++)

for(intb=0;

b<

b++)

{cout.width(10);

char('

A'

+b);

a++)

cout.width(10);

P"

a;

for(intb=0;

b++)

{cout.width(10);

max[a][b];

Allocation[a][b];

Need[a][b];

cout<

Available"

b++){cout.width(10);

Available[b];

\n\n\n"

Procedureprc;

//假设ProID是1

prc.Request[0]=1;

Bankerbnk;

bnk.Available[0]=10;

bnk.max[0][0]=7;

bnk.max[1][0]=3;

bnk.max[2][0]=9;

bnk.max[3][0]=2;

bnk.max[4][0]=4;

bnk.Allocation[0][0]=0;

bnk.Allocation[1][0]=2;

bnk.Allocation[2][0]=3;

bnk.Allocation[3][0]=2;

bnk.Allocation[4][0]=0;

bnk.Need[0][0]=7;

bnk.Need[1][0]=1;

bnk.Need[2][0]=6;

bnk.Need[3][0]=0;

bnk.Need[4][0]=4;

bnk.PrintTable();

bnk.ApplyResource(prc,1);

getchar();

这次实验总体的完成过程比较顺利,得益于一开始就设计好数据结构,省去了很多麻烦。

通过这次实验,我加深了解有关资源申请、避免死锁等概念,并体会了解决死锁和避免死锁的具体实施方法。

实验三页面置换算法

进一步理解父子进程之间的关系。

1.理解内存页面调度的机理。

2.掌握页面置换算法的实现方法。

3.通过实验比较不同调度算法的优劣。

4.培养综合运用所学知识的能力。

页面置换算法是虚拟存储管理实现的关键,通过本次试验理解内存页面调度的机制,在模拟实现FIFO、LRU等经典页面置换算法的基础上,比较各种置换算法的效率及优缺点,从而了解虚拟存储实现的过程。

将不同的置换算法放在不同的子进程中加以模拟,培养综合运用所学知识的能力。

这是一个综合型实验,要求在掌握父子进程并发执行机制和内存页面置换算法的基础上,能综合运用这两方面的知识,自行编制程序。

程序涉及一个父进程和两个子进程。

父进程使用rand()函数随机产生若干随机数,经过处理后,存于一数组Acess_Series[]中,作为内存页面访问的序列。

两个子进程根据这个访问序列,分别采用FIFO和LRU两种不同的页面置换算法对内存页面进行调度。

要求:

1.每个子进程应能反映出页面置换的过程,并统计页面置换算法的命中或缺页情况。

设缺页的次数为diseffect。

总的页面访问次数为total_instruction。

缺页率=disaffect/total_instruction

命中率=1-disaffect/total_instruction

2.将为进程分配的内存页面数mframe作为程序的参数,通过多次运行程序,说明FIFO算法存在的Belady现象。

四、实验程序代码

stdio.h>

sys/types.h>

stdlib.h>

sys/stat.h>

fcntl.h>

error.h>

wait.h>

unistd.h>

main()

intp1,p2;

inti,j,k,t,m,kk,r1,r2;

inttemp1,temp2,temp3;

intdiseffect1=0;

intdiseffect2=0;

intk1=0;

intk2=0;

intf1=0;

intf2=0;

floatf;

intAccess_series[8];

structone_frame{

intpage_no;

charflag;

};

intmframe=5;

structone_frameM_Frame[5];

for(i=0;

mframe;

i++)M_Frame[i].page_no=-1;

printf("

yemian:

);

8;

i++)//产生随机数

{Access_series[i]=rand()%8+1;

%d"

Access_series[i]);

}printf("

\n"

while((p1=fork())==-1);

if(p1==0)

for(j=0;

{r1=Access_series[j];

//读入一个逻辑页面

for(k=0;

k<

k1;

k++)//查找页面是否已存在于物理页面

{if(r1!

=M_Frame[k].page_no)continue;

else

{printf("

havefound!

i++)//存在则显示,并标记,返回读入逻辑页面

printf("

M_Frame[i]);

printf("

f1=1;

break;

}}

if(f1==0)

{diseffect1++;

//若不存在,发生缺页,则失效率加1

if(k1<

mframe)//物理页面没有分配满

M_Frame[k1].page_no=r1;

//分配一个空的物理页面

M_Frame[k1].flag='

Y'

k1++;

for(i=0;

i++)printf("

printf("

diseffect!

%d\n"

diseffect1);

for(i=0;

else

{temp1=M_Frame[0].page_no;

//物理

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

当前位置:首页 > 自然科学 > 化学

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

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