操作系统实验报告.docx

上传人:b****0 文档编号:18376459 上传时间:2023-08-16 格式:DOCX 页数:16 大小:19.53KB
下载 相关 举报
操作系统实验报告.docx_第1页
第1页 / 共16页
操作系统实验报告.docx_第2页
第2页 / 共16页
操作系统实验报告.docx_第3页
第3页 / 共16页
操作系统实验报告.docx_第4页
第4页 / 共16页
操作系统实验报告.docx_第5页
第5页 / 共16页
操作系统实验报告.docx_第6页
第6页 / 共16页
操作系统实验报告.docx_第7页
第7页 / 共16页
操作系统实验报告.docx_第8页
第8页 / 共16页
操作系统实验报告.docx_第9页
第9页 / 共16页
操作系统实验报告.docx_第10页
第10页 / 共16页
操作系统实验报告.docx_第11页
第11页 / 共16页
操作系统实验报告.docx_第12页
第12页 / 共16页
操作系统实验报告.docx_第13页
第13页 / 共16页
操作系统实验报告.docx_第14页
第14页 / 共16页
操作系统实验报告.docx_第15页
第15页 / 共16页
操作系统实验报告.docx_第16页
第16页 / 共16页
亲,该文档总共16页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

操作系统实验报告.docx

《操作系统实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统实验报告.docx(16页珍藏版)》请在冰点文库上搜索。

操作系统实验报告.docx

操作系统实验报告

实验一(生产者—消费者)

一.实验题目生产者与消费者实验

二.实验目的

加深进程的概念的理解,明确进程与程序的区别,深入认识程序并发执行的实质,理解进程竞争资源的现象,互斥与同步的基本概念,掌握相关的API的使用,了解多线程的并发执行机制,实现线程的同步与互斥的基本方法。

三.实验内容

分析已编制的一个“生产者—消费者”实例,并将缺失的代码补充完整,然后调试这段程序,得出最终的结果,并分析此结果,得出相应的结论,尝试改变一些参数,分析这一改变对结果的影响。

四.设计思路和算法

1.利用windows提供的API函数CreateSemaphore()创建信号量对象;CreateThread()创建线程;WaitForSingleObject()执行P操作;ReleaseSemaphore()执行V操作;WaitForMultipleObjects()主进程等待线程的结束等函数进行设计。

2.在Windows中,常见的同步对象有:

信号量(Semaphore)、互斥量(Mutex)。

使用这些对象都分为三个步骤,一是创建或者初始化;接着请求该同步对象,随即进入临界区,这一步对应于互斥量的上锁;最后释放该同步对象,这对应于互斥量的解锁。

这些同步对象在主进程中创建,在其子线程中都可

五.主要数据结构

每个进程有一个进程控制块(PCB)表示。

进程控制块可以包含如下信息:

进程类型标号、进程系统号、进程状态(本程序未用)、进程产品(字符)、进程链指针等等。

系统开辟了一个缓冲区,大小由buffersize指定。

程序中有三个链队列,一个链表。

一个就绪队列(ready),两个等待队列:

生产者等待队列(producer);消费者队列(consumer)。

一个链表(over),用于收集已经运行结束的进程

本程序通过函数模拟信号量的原子操作。

六.程序运行结果

运行程序后的结果:

生产者1准备生产

生产者1开始往缓冲区中写数据

生产者1开始退出缓冲区...

生产者2准备生产

生产者2开始往缓冲区中写数据

生产者2开始退出缓冲区...

消费者1准备消费

消费者1开始消费缓冲区中数据

消费者1开始退出缓冲区...

生产者3准备生产

生产者3开始往缓冲区中写数据

生产者3开始退出缓冲区..

.

消费者2准备消费

消费者2开始消费缓冲区中数据

消费者2开始退出缓冲区...

生产者4准备生产

生产者4开始往缓冲区中写数据

生产者4开始退出缓冲区...

消费者3准备消费

消费者3开始消费缓冲区中数据

消费者3开始退出缓冲区...

生产者5准备生产

生产者5开始往缓冲区中写数据

生产者5开始退出缓冲区...

消费者4准备消费

消费者4开始消费缓冲区中数据

消费者4开始退出缓冲区...

生产者6准备生产

生产者6开始往缓冲区中写数据

生产者6开始退出缓冲区...

消费者5准备消费

消费者5开始消费缓冲区中数据

消费者5开始退出缓冲区...

生产者7准备生产

生产者7开始往缓冲区中写数据

生产者7开始退出缓冲区...

消费者6准备消费

消费者6开始消费缓冲区中数据

消费者6开始退出缓冲区...

生产者8准备生产

生产者8开始往缓冲区中写数据

生产者8开始退出缓冲区...

消费者7准备消费

消费者7开始消费缓冲区中数据

消费者7开始退出缓冲区...

生产者9准备生产

生产者9开始往缓冲区中写数据

生产者9开始退出缓冲区...

消费者8准备消费

消费者8开始消费缓冲区中数据

消费者8开始退出缓冲区...

生产者10准备生产

生产者10开始往缓冲区中写数据

生产者10开始退出缓冲区...

消费者9准备消费

消费者9开始消费缓冲区中数据

消费者9开始退出缓冲区...

消费者10准备消费

消费者10开始消费缓冲区中数据

消费者10开始退出缓冲区...

七.源程序

#include<>

#include<>

#include<>

#include

#include<>

#defineMAX_BUFFER_NUM10

#defineINTE_PER_SEC1000

#defineMAX_THREAD_NUM64

 

strictThreadInfo

{

intoserial;

charentity;

doubledelay;

intothread_request[MAX_THREAD_NUM];

inton_request;

};

CRITICAL_SECTIONPC_Critical[MAX_BUFFER_NUM];

intoBuffer_Critical[MAX_BUFFER_NUM];

HANDLEh_Thread[MAX_THREAD_NUM];

ThreadInfoThread_Info[MAX_THREAD_NUM];

HANDLEempty_semaphore;

HANDLEh_mutex;

DWORDn_Thread=0;

DWORDn_Buffer_or_Critical;

HANDLEh_Semaphore[MAX_THREAD_NUM];

voidProduce(void*p);

voidConsume(void*p);

boolIfInOtherRequest(into);

intoFindProducePositon();

intoFindBufferPosition(into);

intomain(void)

{

DWORDwait_for_all;

ifstreaminFile;

for(intoi=0;i

Buffer_Critical[i]=-1;

for(intoj=0;j

for(intok=0;k

Thread_Info[j].thread_request[k]=-1;

Thread_Info[j].n_request=0;

}

for(i=0;i

InitializeCriticalSection(&PC_Critical[i]);

 

("");

inFile>>n_Buffer_or_Critical;

();

printf("输入文件是:

\n");

printf("%d\n",(into)n_Buffer_or_Critical);

while(inFile){

inFile>>Thread_Info[n_Thread].serial;

inFile>>Thread_Info[n_Thread].entity;

inFile>>Thread_Info[n_Thread].delay;

charc;

(c);

while(c!

='\n'&&!

()){

inFile>>Thread_Info[n_Thread].thread_request[Thread_Info[n_Thread].n_request++];

(c);

}

n_Thread++;

}

for(j=0;j<(into)n_Thread;j++){

intoTemp_serial=Thread_Info[j].serial;

charTemp_entity=Thread_Info[j].entity;

doubleTemp_delay=Thread_Info[j].delay;

printf("\n线程:

%2d%c%f",Temp_serial,Temp_entity,Temp_delay);

intoTemp_request=Thread_Info[j].n_request;

for(intok=0;k

printf("%d",Thread_Info[j].thread_request[k]);

cout<

}

printf("\n\n");

empty_semaphore=CreateSemaphore(NULL,n_Buffer_or_Critical,n_Buffer_or_Critical,

"semaphore_for_empty");

h_mutex=CreateMutex(NULL,FALSE,"mutex_for_update");

for(j=0;j<(into)n_Thread;j++){

std:

:

stringlp="semaphore_for_produce_";

intotemp=j;

while(temp){

charc=(char)(temp%10);

lp+=c;

temp/=10;

}

h_Semaphore[j+1]=CreateSemaphore(NULL,0,n_Thread,());

}

for(i=0;i<(into)n_Thread;i++){

if(Thread_Info[i].entity=='P')

h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),

&(Thread_Info[i]),0,NULL);

else

h_Thread[i]=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume),

&(Thread_Info[i]),0,NULL);

}

wait_for_all=WaitForMultipleObjects(n_Thread,h_Thread,TRUE,-1);

printf("\n\n所有生产和消费已经完成他们的工作。

\n");

printf("Pressanykeytoquit!

\n");

_getch();

return0;

}

 

boolIfInOtherRequest(intoreq)

{

for(intoi=0;i

for(intoj=0;j

if(Thread_Info[i].thread_request[j]==req)

returnTRUE;

returnFALSE;

}

 

intoFindProducePosition()

{

intoEmptyPosition;

for(intoi=0;i

if(Buffer_Critical[i]==-1){

EmptyPosition=i;

Buffer_Critical[i]=-2;

break;

}

returnEmptyPosition;

}

 

intoFindBufferPosition(intoProPos)

{

intoTempPos;

for(intoi=0;i

if(Buffer_Critical[i]==ProPos){

TempPos=i;

break;

}

returnTempPos;

}

 

voidProduce(void*p)

{

DWORDwait_for_semaphore,wait_for_mutex,m_delay;

intom_serial;

 

m_serial=((ThreadInfo*)(p))->serial;

m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);

Sleep(m_delay);

printf("生产者%2d发送生产请求信号.\n",m_serial);

wait_for_semaphore=WaitForSingleObject(empty_semaphore,-1);

wait_for_mutex=WaitForSingleObject(h_mutex,-1);

intoProducePos=FindProducePosition();

ReleaseMutex(h_mutex);

printf("生产者%2d开始生产产品的缓冲区%2d.\n",m_serial,ProducePos);

Buffer_Critical[ProducePos]=m_serial;

printf("生产者%2d完成生产过程:

\n",m_serial);

printf("缓冲区[%2d]:

%3d\n",ProducePos,Buffer_Critical[ProducePos]);

ReleaseSemaphore(h_Semaphore[m_serial],n_Thread,NULL);

}

voidConsume(void*p)

{

DWORDwait_for_semaphore,m_delay;

intom_serial,m_requestNum;

intom_thread_request[MAX_THREAD_NUM];

m_serial=((ThreadInfo*)(p))->serial;

m_delay=(DWORD)(((ThreadInfo*)(p))->delay*INTE_PER_SEC);

m_requestNum=((ThreadInfo*)(p))->n_request;

for(intoi=0;i

m_thread_request[i]=((ThreadInfo*)(p))->thread_request[i];

 

Sleep(m_delay);

for(i=0;i

printf("消费者%2d请求消费%2d产品\n",m_serial,m_thread_request[i]);

wait_for_semaphore=WaitForSingleObject(h_Semaphore[m_thread_request[i]],-1);

intoBufferPos=FindBufferPosition(m_thread_request[i]);

EnterCriticalSection(&PC_Critical[BufferPos]);

printf("消费者%2d开始消费%2d产品\n",m_serial,m_thread_request[i]);

((ThreadInfo*)(p))->thread_request[i]=-1;

if(!

IfInOtherRequest(m_thread_request[i])){

Buffer_Critical[BufferPos]=-1;

printf("消费者%2d完成消费%2d:

\n",m_serial,m_thread_request[i]);

printf("缓冲区[%2d]:

%3d\n",BufferPos,Buffer_Critical[BufferPos]);

ReleaseSemaphore(empty_semaphore,1,NULL);

}

else{

printf("消费者%2d完成消费产品%2d\n",m_serial,m_thread_request[i]);

}

LeaveCriticalSection(&PC_Critical[BufferPos]);

}

}

八.实验心得体会

通过本次实验,要明白进程的概念的理解,明确进程与程序的区别,深入认识程序并发执行的实质,理解进程竞争资源的现象,互斥与同步的基本概念,进程的并发控制。

 

实验二(进程死锁模拟试验)

一.实验题目进程死锁模拟实验

二.实验目的

进一步了解线程的概念,熟悉进程线程的同步概念,观察死锁发生的现象,了解死锁发生的原因。

掌握如何判断死锁发生的方法。

三.实验内容

本次实验模拟两个线程完成销售车票的过程。

一方面,利用关键代码实现线程同步,另一方面模拟实现线程死锁。

四.设计思路和算法

死锁现象是操作系统各个进程竞争系统中有限的资源引起的。

如果随机给进程分配资源,就可能发生死锁,因此就应有办法检测死锁的发生。

本次实验中采用“银行家算法”判断死锁的发生。

五.实验的主要数据结构和说明

主要是启动两个线程,进行判断,以临界区进行划分,本实验设计一个3个并发进程共享3种系统资源且每种系统资源有10个的系统。

系统能显示各种进程的进展情况以及检察是否有错误和死锁现象产生。

六.程序运行结果

 

七.源程序

#include<>

#include<>

DWORDWINAPIFun1Proc(LPVOIDlpParameter);验主要内容

编写程序完成页式虚拟存储管理中地址转换过程和模拟缺页中断的处理。

实验具体内容包括:

首先对给定的地址进行转换工作,若发现缺页则先进行缺页中断处理,然后再进行地址转换;最后编写主函数对所做工作进行测试。

假定主存64KB,每个主存块1024字节,作业最大支持到64KB,系统中每个作业分得主存块4块。

四.设计思路和算法

(1)地址转换过程:

首先从逻辑地址中的高位取得页号,然后根据页号查页表,得到块号;然后从逻辑地址中的低位取得页内地址,将块号和页内地址拼接即得到物理地址。

(2)缺页中断处理

根据页号查找页表,判断该页是否再主存储器中,若该页标志位“0”,形成缺页中断。

然后执行缺页中断处理程序进行处理。

(3)实验方法与步骤

实现地址转换与缺页中断处理,主要考虑三个问题:

第一,设计页式虚拟存储管理方式中页表的数据结构;第二,地址转换算法的实现;第三,缺页中断处理算法的实现。

五.设计页表的数据结构

(1)页式虚拟存储管理方式中页表除了页号和该页对应的主存块号外,至少还要包括存在标志(该页是否在主存),磁盘位置(该页的副本在磁盘上的位置)和修改标志(该页是否修改过)。

在实验中页表用数组模拟,其数据结构定义如下:

strict{

intolumber; 1”0”1”0”1”1”1”程序           

air#include

#definen64      1”0”1”umber=lumber;

page[i].flag=0;

page[i].write=0;

page[i].dumber=dumber;

i++;

cout<<"请输入页号和辅存地址:

";

cin>>lumber>>dumber;

}

umber=number;

page[m].flag=1;rite==1)

cout<<"将页"<

<

page[j].flag=0;

page[lumber].number=page[j].number;

page[lumber].flag=1;

page[lumber].write=0;

cout<<"淘汰主存块"<

<

<

<

}

lag==1){  umber;

paddress=number<<10|ad;

cout<<"逻辑地址是:

"<

?

<

if(write==1)     rite=1;

}

else{  //页号为lumber不在内存当中,则产生缺页中断

pageinterrupt(lumber);

gotokk;

}

}//command

";

";

七.实验心得体会

通过本次实验让我明白了许多,做事要认真仔细,页式存储管理怎么去执行,掌握请调策略,放置策略,淘汰策略,怎样进行页式地址转换,选用什么置换算法最好。

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

当前位置:首页 > 人文社科 > 法律资料

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2