操作系统实验报告_第1页
操作系统实验报告_第2页
操作系统实验报告_第3页
操作系统实验报告_第4页
操作系统实验报告_第5页
免费预览已结束,剩余31页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验一(生产者消费者)一 实验题目 生产者与消费者实验二 实验目的加深进程的概念的理解,明确进程与程序的区别,深入认识程序并发执行的实质,理解进程竞争资源的现象,互斥与同步的基本概念,掌握相关的API的使用,了解多线程的并发执行机制,实现线程的同步与互斥的基本方法。三 实验内容分析已编制的一个“生产者消费者”实例,并将缺失的代码补充完整,然后调试这段程序,得出最终的结果,并分析此结果,得出相应的结论,尝试改变一些参数,分析这一改变对结果的影响。四 设计思路和算法1. 利用windows提供的API函数CreateSemaphore()创建信号量对象;Create Thread()创建线程;WaitForSingleObject()执行P操作;Release Semaphore()执行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#define MAX_BUFFER_NUM10#define INTE_PER_SEC 1000#define MAX_THREAD_NUM 64strict ThreadInfointoserial;charentity; doubledelay;intothread_requestMAX_THREAD_NUM; inton_request;CRITICAL_SECTIONPC_CriticalMAX_BUFFER_NUM;into Buffer_CriticalMAX_BUFFER_NUM; HANDLE h_ThreadMAX_THREAD_NUM; ThreadInfoThread_InfoMAX_THREAD_NUM; HANDLEempty_semaphore;HANDLEh_mutex;DWORDn_Thread = 0; DWORDn_Buffer_or_Critical; HANDLEh_SemaphoreMAX_THREAD_NUM;void Produce(void *p);void Consume(void *p);bool IfInOtherRequest(into);into FindProducePositon();into FindBufferPosition(into);into main(void)DWORDwait_for_all;ifstreaminFile;for(into i=0;i MAX_BUFFER_NUM;i+)Buffer_Criticali = -1;for(into j=0;jMAX_THREAD_NUM;j+)for(into k=0;kMAX_THREAD_NUM;k+)Thread_Infoj.thread_requestk = -1;Thread_Infoj.n_request = 0;for(i =0;i n_Buffer_or_Critical;inFile.get();printf(输入文件是:n);printf(%d n,(into) n_Buffer_or_Critical);while(inFile)inFile Thread_Infon_Thread.serial;inFile Thread_Infon_Thread.entity;inFile Thread_Infon_Thread.delay;char c;inFile.get(c);while(c!=n& !inFile.eof() inFile Thread_Infon_Thread.thread_requestThread_Infon_Thread.n_request+; inFile.get(c);n_Thread+; for(j=0;j(into) n_Thread;j+)into Temp_serial = Thread_Infoj.serial;char Temp_entity = Thread_Infoj.entity;double Temp_delay = Thread_Infoj.delay;printf( n 线程:%2d %c %f ,Temp_serial,Temp_entity,Temp_delay);into Temp_request = Thread_Infoj.n_request;for(into k=0;kTemp_request;k+)printf( %d , Thread_Infoj.thread_requestk);coutendl;printf(nn); 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:string lp =semaphore_for_produce_;into temp =j;while(temp)char c = (char)(temp%10);lp+=c;temp/=10;h_Semaphorej+1=CreateSemaphore(NULL,0,n_Thread,lp.c_str();for(i =0;i (into) n_Thread;i+)if(Thread_Infoi.entity =P)h_Threadi= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Produce),&(Thread_Infoi),0,NULL);else h_Threadi=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(Consume),&(Thread_Infoi),0,NULL);wait_for_all = WaitForMultipleObjects(n_Thread,h_Thread,TRUE,-1);printf( n n所有生产和消费已经完成他们的工作。 n);printf(Press any key to quit!n);_getch();return 0;bool IfInOtherRequest(into req)for(into i=0;in_Thread;i+)for(into j=0;jThread_Infoi.n_request;j+)if(Thread_Infoi.thread_requestj = req)return TRUE;return FALSE;intoFindProducePosition()into EmptyPosition;for (into i =0;in_Buffer_or_Critical;i+)if(Buffer_Criticali = -1)EmptyPosition = i;Buffer_Criticali = -2;break;return EmptyPosition;into FindBufferPosition(into ProPos)into TempPos;for (into i =0 ;iserial;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);into ProducePos = FindProducePosition(); ReleaseMutex(h_mutex);printf(生产者 %2d 开始生产产品的缓冲区 %2d.n,m_serial,ProducePos);Buffer_CriticalProducePos = m_serial;printf(生产者 %2d 完成生产过程 :n ,m_serial);printf( 缓冲区 %2d :%3d n ,ProducePos,Buffer_CriticalProducePos);ReleaseSemaphore(h_Semaphorem_serial,n_Thread,NULL);void Consume(void * p)DWORDwait_for_semaphore,m_delay;intom_serial,m_requestNum; intom_thread_requestMAX_THREAD_NUM; m_serial = (ThreadInfo*)(p)-serial;m_delay = (DWORD)(ThreadInfo*)(p)-delay *INTE_PER_SEC);m_requestNum = (ThreadInfo *)(p)-n_request;for (into i = 0;ithread_requesti;Sleep(m_delay);for(i =0;ithread_requesti =-1; if(!IfInOtherRequest(m_thread_requesti)Buffer_CriticalBufferPos = -1;printf(消费者%2d 完成消费 %2d:n ,m_serial,m_thread_requesti);printf( 缓冲区 %2d :%3d n ,BufferPos,Buffer_CriticalBufferPos);ReleaseSemaphore(empty_semaphore,1,NULL); elseprintf(消费者 %2d 完成消费 产品 %2dn ,m_serial,m_thread_requesti); LeaveCriticalSection(&PC_CriticalBufferPos);八实验心得体会通过本次实验,要明白进程的概念的理解,明确进程与程序的区别,深入认识程序并发执行的实质,理解进程竞争资源的现象,互斥与同步的基本概念,进程的并发控制。实验二(进程死锁模拟试验)一.实验题目 进程死锁模拟实验二.实验目的进一步了解线程的概念,熟悉进程线程的同步概念,观察死锁发生的现象,了解死锁发生的原因。掌握如何判断死锁发生的方法。三实验内容本次实验模拟两个线程完成销售车票的过程。一方面,利用关键代码实现线程同步,另一方面模拟实现线程死锁。四.设计思路和算法死锁现象是操作系统各个进程竞争系统中有限的资源引起的。如果随机给进程分配资源,就可能发生死锁,因此就应有办法检测死锁的发生。本次实验中采用“银行家算法”判断死锁的发生。五.实验的主要数据结构和说明主要是启动两个线程,进行判断,以临界区进行划分,本实验设计一个3个并发进程共享3种系统资源且每种系统资源有10个的系统。系统能显示各种进程的进展情况以及检察是否有错误和死锁现象产生。六.程序运行结果七.源程序#include #include DWORD WINAPI Fun1Proc(LPVOID lpParameter);/threadDWORD WINAPI Fun2Proc(LPVOID lpParameter);/threadint tickets=100;CRITICAL_SECTION g_csA;void main()HANDLE hThread1;HANDLE hThread2;hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);CloseHandle(hThread1);CloseHandle(hThread2);InitializeCriticalSection(&g_csA);Sleep(4000);DeleteCriticalSection(&g_csA);DWORD WINAPI Fun1Proc(LPVOID lpParameter)while(true)EnterCriticalSection(&g_csA);Sleep(1);if(tickets0)Sleep(1);coutthread1 sell ticket:tickets-0)Sleep(1);coutthread2 sell ticket:tickets-endl;LeaveCriticalSection(&g_csA);elseLeaveCriticalSection(&g_csA);break;return 0;#include #include DWORD WINAPI Fun1Proc(LPVOID lpParameter);/threadDWORD WINAPI Fun2Proc(LPVOID lpParameter);/threadint tickets=100;CRITICAL_SECTION g_csA;CRITICAL_SECTION g_csB;void main()HANDLE hThread1;HANDLE hThread2;hThread1=CreateThread(NULL,0,Fun1Proc,NULL,0,NULL);hThread2=CreateThread(NULL,0,Fun2Proc,NULL,0,NULL);CloseHandle(hThread1);CloseHandle(hThread2);InitializeCriticalSection(&g_csA); InitializeCriticalSection(&g_csB); Sleep(4000);DeleteCriticalSection(&g_csA);DWORD WINAPI Fun1Proc(LPVOID lpParameter)while(true)EnterCriticalSection(&g_csA);Sleep(1);if(tickets0)EnterCriticalSection(&g_csB);Sleep(1);coutthread1 sell ticket:tickets-0)EnterCriticalSection(&g_csA);Sleep(1);coutthread2 sell ticket:tickets-endl;LeaveCriticalSection(&g_csB);elseLeaveCriticalSection(&g_csA);break;return 0;八实验心得体会通过本次实验明白进程的概念,进程的并发控制,进程的状态转换,在什么情况下发生什么,进程阻塞,互斥,怎么样会发生死锁。实验三(页式虚拟存储管理中地址转换和页式中断)一实验题目 页式虚拟存储管理中地址转换和页式中断二实验目的深入了解页式存储管理如何实现地址转换;进一步认识页式虚拟存储管理中如何处理缺页中断以及页面置换算法,深入了解页式虚拟存储管理如何实现地址转换。三.实验主要内容编写程序完成页式虚拟存储管理中地址转换过程和模拟缺页中断的处理。实验具体内容包括:首先对给定的地址进行转换工作,若发现缺页则先进行缺页中断处理,然后再进行地址转换;最后编写主函数对所做工作进行测试。假定主存64KB,每个主存块1024字节,作业最大支持到64KB,系统中每个作业分得主存块4块。四.设计思路和算法(1)地址转换过程:首先从逻辑地址中的高位取得页号,然后根据页号查页表,得到块号;然后从逻辑地址中的低位取得页内地址,将块号和页内地址拼接即得到物理地址。(2)缺页中断处理根据页号查找页表,判断该页是否再主存储器中,若该页标志位“0”,形成缺页中断。然后执行缺页中断处理程序进行处理。 (3)实验方法与步骤实现地址转换与缺页中断处理,主要考虑三个问题:第一,设计页式虚拟存储管理方式中页表的数据结构;第二,地址转换算法的实现;第三,缺页中断处理算法的实现。五.设计页表的数据结构(1)页式虚拟存储管理方式中页表除了页号和该页对应的主存块号外,至少还要包括存在标志(该页是否在主存),磁盘位置(该页的副本在磁盘上的位置)和修改标志(该页是否修改过)。在实验中页表用数组模拟,其数据结构定义如下:strictinto lumber; /页号into flag; /表示页是否在主存中,“1”表示在,“0”表示不在into number; / 该页所在主存块的块号into write; /该页是否被修改过,“1”表示修改过,“0“表示没有修改过into dumber; /该页存放在磁盘上的位置,即磁盘块号pagen; /页表定义(2)地址转换算法的实现地址转换是由硬件完成的,实验中使用软件程序模拟地址转换过程。在实验中,每个主存块1024字节,则块内地址占10位;主存64KB,则主存共64块,即块号占6位;物理地址共占16位;作业最大64KB,则作业最大占64块,即页号占6位,逻辑地址共占16位。(用主存的大小计算物理地址位数,用最大作业大小计算逻辑地址位数)。在页式虚拟存储管理方式中,作业信息作为副本放在磁盘上,作业执行时仅把作业信息的部分页面装入主存储器,作业执行时若访问的页面在主存中,则进行地址转换,若访问的页面不在主存中,则产生一个“缺页中断”,由操作系统把当前所需要的页面装入主存储器后,再次执行时才可以按上述方法进行地址转换。(3) 缺页中断处理算法的实现缺页处理过程简单阐述如下: 1) 根据当前执行指令中逻辑地址的页号查找页表,判断该页是否在主存储器中,若该页标志为“0”,形成缺页中断。中断装置通过交换PSW让操作系统的中断处理程序占用处理器。 2) 操作系统处理缺页中断的方法是查主存分配表,找一个空闲主存块;若无空闲块,查页表,选择一个已在主存的页面,把它暂时调出主存。若在执行过程中该页被修改过,则需将该页信息写回磁盘,否则不必写回; 3) 找出该页的位置,启动磁盘读出该页的信息,把磁盘上读出的信息装入到主存块,修改页表中该页的标志为“1”; 4) 由于产生缺页中断的那条指令还没有执行完,所以页面装入后应该重新执行被中断的指令。当重新执行该指令时,由于要访问的页面已在主存中,所以可以正常执行。关于第二步的查找装入新页面的主存块处理方式,不同系统采用的策略可能有所不同,这里采用局部置换算法,就是每个作业分得一定的主存块,只能在分得的主存块内查找空闲块,若无空闲主存块,则从该作业中选择一个页面淘汰出主存。实验中采用局部置换算法。 使用局部置换算法时,存在这样一个问题:就是在分配给作业主存空间时,装入哪些页?有的系统采取不装入任何一页,当执行过程中需要时才将其调入。有点系统采用页面预置的方法,事先估计可能某些页面会先用到,在分配主存块后将这些页面装入。在本实验中采用第二种方法,分配主存空间时将前几页调入主存,假定系统中每个作业分得主存块m 块,则将第 0m-1页装入主存。 因为是模拟硬件工作,所有在实验中如果访问的页不在主存中时,则输入该页页号,表示硬件产生缺页中断,然后直接转去缺页中断处理;由于采用页面预置方法,在给定的主存块中一定无空闲块,只能淘汰已在主存的一页;没有启动磁盘的工作,淘汰的页面需要写回磁盘时,用输入页号表示,调入新的一页时,将该页在页表中的存在标志置为“1”,输出页号表示将该页调入主存。 当主存中无空闲块时,为装入一个页面,必须按照某种页面调度算法从已在主存的页中选择一页,将它暂时调出主存,让出主存空间,用来存放装入的页面。常用的页面调度算法有:先进先出、最近最少用算法、和最近最不常用算法。在本实验中采用先进现出调度算法。先进先出算法总是选择驻留在主存时间最长的一页调出。实验中把主存储器的页的页号按照进入主存的先后次序排成队列,每次总是调出对首的页,当装入一个新页后,把新页的页号排入队尾。实验中,用一个数组存放页号的队列。假定分配给作业的主存块数为m,数组可由m个元素组成,p0,p1,p2pm-1;队首指针head;采用页面预置的方法,页号队列的长度总是m,tail等于(head+1)%m。因此可以使用一个指针,只用head即可。在装入一个新的页时,装入页和淘汰页同时执行,当装入一个新的页时,将其页号存入数组:淘汰页的页号phead;phead=新装入页的页号;head=(head+1)%m; 实验执行一条指令时,不模拟指令的执行,只是考虑指令执行是否修改页面,若修改页面,则将该页的页表中的修改标志位置“1”,然后输出转换后的物理地址,并输出物理地址来表示一条指令执行完成;如果访问的页不在主存时,则产生缺页中断,然后直接转去缺页中断处理,最后模拟中断返回,就是返回冲进进行地址转换。因为没有实际主存,所有在模拟程序中首先手工输入页表信息,创建该作业的页表;然后循环执行假定的指令,观察地址转换情况。六.源程序air #include#define n 64 /页表的最大长度#define length 4 /系统为每个作业分配的主存块数strictinto lumber; /页号into flag; /表示页是否在主存中,“1”表示在,“0”表示不在into number; /该页所在主存块的块号into write; /该页是否被修改过,“1”表示修改过,“0“表示没有修改过into dumber; /该页存放在磁盘上的位置,即磁盘块号pagen; /页表定义into m;into page length; /页表的实际长度into plength; /用向量模拟主存into head;void page interrupt(into); /缺页中断处理函数void command(unsigned, into); /命令处理函数void main()into lnumber,pnumber,write,dnumber;unsigned laddress;into i;cout输入页表的信息,创建页表(页号从0开始,若页号为1,则结束输入) ;coutlumberdumber;cin.ignore ();i=0;while(lumber!=-1)pagei.lumber=lumber;pagei.flag=0;pagei.write=0;pagei.dumber=dumber;i+;coutlumberdumber;/预先将输入的页调入主存块中page length=i;cout输入主存块号(输入少于或者等于inumber; cin.ignore ();m=0;head=0;while(mLENGTH&PN

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论