欢迎来到三一办公! | 帮助中心 三一办公31ppt.com(应用文档模板下载平台)
三一办公
全部分类
  • 办公文档>
  • PPT模板>
  • 建筑/施工/环境>
  • 毕业设计>
  • 工程图纸>
  • 教育教学>
  • 素材源码>
  • 生活休闲>
  • 临时分类>
  • ImageVerifierCode 换一换
    首页 三一办公 > 资源分类 > DOC文档下载  

    操作系统课程设计报告读者写着问题.doc

    • 资源ID:3926914       资源大小:89KB        全文页数:13页
    • 资源格式: DOC        下载积分:8金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要8金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    操作系统课程设计报告读者写着问题.doc

    计算机与信息学院操作系统课程设计报告一、 开题报告(一) 该项课程设计的意义;1. 更加深入的了解读者写者问题的算法;2. 加深对线程,进程的理解;3. 加深对“线程同步”概念的理解,理解并应用“信号量机制”;4. 熟悉计算机对处理机的管理,了解临界资源的访问方式;5. 了解C+中线程的实现方式,研读API。(二) 课程设计的任务多进程/线程编程:读者-写者问题。 l 设置两类进程/线程,一类为读者,一类为写者;l 随机启动读者或写者;l 显示读者或写者执行状态;l 随着进程/线程的执行,更新显示;(三) 相关原理及算法描述;整体概况:该程序从大体上来分只有两个模块,即“读者优先”和“写者优先”模块. 读者优先:如果没有写者正在操作,则读者不需要等待,用一个整型变量readcount记录读者数目,用于确定是否释放读者线程,readcount的初值为0.当线程开始调入时.每个读者准备读. 等待互斥信号,保证对readcount 的访问,修改互斥.即readcount+.而当读者线程进行读操作时,则读者数目减少(readcount-).当readcout=0 时,说明所有的读者都已经读完,离开临界区唤醒写者(LeaveCriticalSection(&RP_Write);), 释放互斥信号(ReleaseMutex(h_Mutex).还需要一个互斥对象mutex来实现对全局变量Read_count修改时的互斥. 另外,为了实现写-写互斥,需要增加一个临界区对象Write。当写者发出写请求时,必须申请临界区对象的所有权。通过这种方法,可以实现读-写互斥,当Read_count=1时(即第一个读者到来时),读者线程也必须申请临界区对象的所有权写者优先:写者优先与读者不同之处在于一旦一个写者到来,它应该尽快对文件进行写操作,如果有一个写者在等待,则新到来的读者不允许进行读操作。为此应当填加一个整形变量write_count,用于记录正在等待的写者的数目,write_count的初值为0.当线程开始调入时.只允许一个写者准备读. 等待互斥信号,保证对write_count 的访问,修改互斥.即write_count+.而当写者线程进行读操作时,则相应写者数目减少(write_count-).当write_count=0 时,说明所有的读者都已经读完,离开临界区唤醒读者,释放互斥信号.为了实现写者优先,应当填加一个临界区对象read,当有写者在写文件或等待时,读者必须阻塞在read上。(四) 开发环境;VC+6.0(五) 预期设计目标;读者-写者问题的读写操作限制(包括读者优先和写者优先)1.写-写互斥:不能有两个写者同时进行写操作2.读-写互斥:不能同时有一个线程在读,而另一个线程在写。3.读-读允许:可以有一个或多个读者在读。若读者的优先权比写者高, 如果读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作.不必经过别的操件若读者的优先权比写者高,如果第一个写者已经占有了文件的时候.则别的读者必需等待该操作完成后.才能开始读操作.若写者的优先权比读者高, 在一个写者提出要访问文件时,就必须使其尽可能的得到文件,而且不用调配。完成课程设计的任务,实现读者写者问题的全部要求,同时可以实现“读者优先”和“写者优先”两种情况,有时间的话,争取实现可视化图形界面。二、 课程设计报告(一) 课程设计任务、要求、目的;任务和要求:多进程/线程编程:读者-写者问题。 l 设置两类进程/线程,一类为读者,一类为写者;l 随机启动读者或写者;l 显示读者或写者执行状态;l 随着进程/线程的执行,更新显示;目的:1 更加深入的了解读者写者问题的算法;2 加深对线程,进程的理解;3 加深对“线程同步”概念的理解,理解并应用“信号量机制”;4 熟悉计算机对处理机的管理,了解临界资源的访问方式;5 了解C+中线程的实现方式,研读API。(二) 原理及算法描述;写者优先原理图:读者优先原理图:算法描述:读者优先的附加限制:如果读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。写者优先的附加限制:如果一个读者申请进行读操作时已有另一个写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。(三) 开发环境;VC+6.0(四) 重要算法和设计思路描述;整体概况:该程序从大体上来分只有两个模块,即“读者优先”和“写者优先”模块. 读者优先:如果没有写者正在操作,则读者不需要等待,用一个整型变量readcount记录读者数目,用于确定是否释放读者线程,readcount的初值为0.当线程开始调入时.每个读者准备读. 等待互斥信号,保证对readcount 的访问,修改互斥.即readcount+.而当读者线程进行读操作时,则读者数目减少(readcount-).当readcout=0 时,说明所有的读者都已经读完,离开临界区唤醒写者(LeaveCriticalSection(&RP_Write);), 释放互斥信号(ReleaseMutex(h_Mutex).还需要一个互斥对象mutex来实现对全局变量Read_count修改时的互斥. 另外,为了实现写-写互斥,需要增加一个临界区对象Write。当写者发出写请求时,必须申请临界区对象的所有权。通过这种方法,可以实现读-写互斥,当Read_count=1时(即第一个读者到来时),读者线程也必须申请临界区对象的所有权写者优先:写者优先与读者不同之处在于一旦一个写者到来,它应该尽快对文件进行写操作,如果有一个写者在等待,则新到来的读者不允许进行读操作。为此应当填加一个整形变量write_count,用于记录正在等待的写者的数目,write_count的初值为0.当线程开始调入时.只允许一个写者准备读. 等待互斥信号,保证对write_count 的访问,修改互斥.即write_count+.而当写者线程进行读操作时,则相应写者数目减少(write_count-).当write_count=0 时,说明所有的读者都已经读完,离开临界区唤醒读者,释放互斥信号.为了实现写者优先,应当填加一个临界区对象read,当有写者在写文件或等待时,读者必须阻塞在read上。(五) 程序实现-数据结构;相关WindowsAPI说明:CreateThread: 创建一个在调用进程的地址空间中执行的线程。ExitThread Sleep: 对指定的时间间隔挂起当前的执行线程CreateMutex: 创建有名或者无名的互斥对象ReleaseMutex:WaitForSingleObject: 当发生(1)指定对象处于信号态(2)超时 则该函数返回WaitForMultipleObject: 任意一个或全部指定对象处于信号态或超时间隔已过时,返回CreateSemapore: 创建一个有名或无名信号对象。ReleaseSemapore: InitializeCriticalSection: 初始化临界区对象EnterCriticalSection: 等待指定临界区对象的所有权。当调用线程被赋予所有权时,返回。LeaveCriticalSection:该函数释放指定临界区对象的所有权。(六) 程序实现-程序清单;#include <windows.h>/#include <ctype.h>/#include <stdio.h>/#include <string.h>/#include <stdlib.h>/#include <malloc.h>#include<iostream>using namespace std;#define MAX_PERSON 100 /最多100人#define READER 0 /读者#define WRITER 1 /写者#define END -1 /结束/#define R READER/#define W WRITERtypedef struct HANDLE m_hThread;/定义处理线程的句柄int Type;/进程类型(读写)int StartTime;/开始时间int WorkTime;/运行时间int ID;/进程号Person;Person PersonsMAX_PERSON;int NumOfPerson = 0;long CurrentTime= 0;/基本时间片数int PersonLists = /进程队列1, WRITER, 3, 5,2, WRITER, 16, 5,3, READER, 2, 2,4, WRITER, 6, 5,5, READER, 4, 3,6, READER, 17,7,END,;int NumOfReading = 0;int NumOfWriteRequest = 0;/申请写进程的个数HANDLE ReadSemaphore;/读者信号HANDLE WriteSemaphore;/写者信号bool finished = false; /所有的读完成/bool wfinished = false; /所有的写完成void CreatePersonList(int *pPersonList);bool CreateReader(int StartTime,int WorkTime,int ID);bool CreateWriter(int StartTime,int WorkTime,int ID);DWORD WINAPI ReaderProc(LPVOID lpParam);DWORD WINAPI WriterProc(LPVOID lpParam);int main()ReadSemaphore = CreateSemaphore(NULL,1,100,NULL); /创建信号量,当前可用的资源数为1,最大为100/*HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, /lpSemaphoreAttributes为安全属性 LONG lInitialCount, /lInitialCount为Semaphore的初始值 LONG lMaximumCount, /lMaximumCount为最大值 LPCTSTR lpName /lpName为Semaphore对象的名字,NULL表示创建匿名Semaphore );*/WriteSemaphore = CreateSemaphore(NULL,1,100,NULL); /创建信号量,当前可用的资源数为1,最大为100CreatePersonList(PersonLists); / 创建所有读者写者cout<<"创建所有的读者写者"<<"n.n"CurrentTime = 0;while(true)CurrentTime+;Sleep(300); / 300 mscout<<"当前时间 = "<<CurrentTime<<endl;if(finished) return 0;/ return 0;void CreatePersonList(int *pPersonLists)int i=0;int *pList = pPersonLists;bool Ret;while(pList0 != END)switch(pList1)case READER:Ret = CreateReader(pList2,pList3,pList0);break;case WRITER:Ret = CreateWriter(pList2,pList3,pList0);break;if(!Ret)printf("Create Person %d is wrongn",pList0);pList += 4; / 寻找下一个读者或者写者 bool CreateReader(int StartTime,int WorkTime,int ID)DWORD dwThreadID;if(NumOfPerson >= MAX_PERSON)return false;Person *pPerson = &PersonsNumOfPerson;pPerson->ID = ID;pPerson->StartTime = StartTime;pPerson->WorkTime = WorkTime;pPerson->Type = READER;NumOfPerson+;/ 新建进程pPerson->m_hThread= CreateThread(NULL,0,ReaderProc,(LPVOID)pPerson,0,&dwThreadID); /*HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, / pointer to security attributes 安全属性 DWORD dwStackSize, / initial thread stack size 堆栈大小 LPTHREAD_START_ROUTINE lpStartAddress, / pointer to thread function 函数指针 LPVOID lpParameter, / argument for new thread DWORD dwCreationFlags, / creation flags LPDWORD lpThreadId / pointer to receive thread ID );*/if(pPerson->m_hThread = NULL)return false;return true;bool CreateWriter(int StartTime,int WorkTime,int ID) DWORD dwThreadID;if(NumOfPerson >= MAX_PERSON) return false;Person *pPerson = &PersonsNumOfPerson;pPerson->ID = ID;pPerson->StartTime = StartTime;pPerson->WorkTime = WorkTime;pPerson->Type = WRITER;NumOfPerson+;/ 新建进程pPerson->m_hThread= CreateThread(NULL,0,WriterProc,(LPVOID)pPerson,0,&dwThreadID);/*HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, / pointer to security attributes 安全属性 DWORD dwStackSize, / initial thread stack size 堆栈大小 LPTHREAD_START_ROUTINE lpStartAddress, / pointer to thread function 函数指针 LPVOID lpParameter, / argument for new thread DWORD dwCreationFlags, / creation flags LPDWORD lpThreadId / pointer to receive thread ID );*/if(pPerson->m_hThread = NULL)return false;return true;DWORD WINAPI ReaderProc(LPVOID lpParam)/读过程Person *pPerson = (Person *)lpParam;/ 等待启动时间while(CurrentTime != pPerson->StartTime)/读操作还没有到达执行时间,则等待printf("Reader %d is Requesting .n",pPerson->ID);printf("nn*n");/等待写者请求/该语句在写者优先的时候是认为写者优先级高于读者,在有写者的时候读者需要等候,而在读者优先的时候,不用判断是否存在写者,有读者时即开始读操作。 while(NumOfWriteRequest != 0)/NumOfWriteRequest != 0 表示有写者在等待,不能读/等待ReadSemaphore读信号,即当ReadSemaphore有信号时等待结束,相当于p操作WaitForSingleObject(ReadSemaphore,INFINITE); /*DWORD WaitForMultipleObjects( CONST HANDLE *lpHandles, / pointer to the object-handle array DWORD dwMilliseconds / time-out interval in milliseconds );*/if(NumOfReading = 0)/当第一个读者到了,如果WriteSemaphore信号灯灭了,说明有写者在写,读者必须等待,即互斥写操作WaitForSingleObject(WriteSemaphore,INFINITE); NumOfReading+;/还有读者,但是允许下一个读进程读取,相当于V操作ReleaseSemaphore(ReadSemaphore,1,NULL); /*BOOL ReleaseSemaphore(HANDLE hSemaphore,/lpReleaseCount参数表示要增加的数值LONG lReleaseCount, /lpPreviousCount参数用于返回之前的计算值,如果不需要可以设置为NULL LPLONG lpPreviousCount);*/ 启动读者pPerson->StartTime = CurrentTime; printf("Reader %d is Reading the Critical Section.n",pPerson->ID);printf("nn*n"); while(CurrentTime <= pPerson->StartTime + pPerson->WorkTime)/ . 执行读操作printf("Reader %d is Exit.n",pPerson->ID);printf("nn*n");WaitForSingleObject(ReadSemaphore,INFINITE);NumOfReading-;if(NumOfReading = 0) ReleaseSemaphore(WriteSemaphore,1,NULL);/此时没有读者,可以写ReleaseSemaphore(ReadSemaphore,1,NULL);if(pPerson->ID = 6 ) finished = true; /所有的读写完成ExitThread(0);return 0;DWORD WINAPI WriterProc(LPVOID lpParam)Person *pPerson = (Person *)lpParam;/ 等待启动时间while(CurrentTime != pPerson->StartTime) printf("Writer %d is Requesting .n",pPerson->ID);printf("nn*n"); NumOfWriteRequest+;/在写者优先的时候需要用自加来初始信号值,而在读者优先的时是通过读者操作来控制信号值WaitForSingleObject(WriteSemaphore,INFINITE);/ 启动写者pPerson->StartTime = CurrentTime; printf("Writer %d is Writting the Critical Section.n",pPerson->ID);while(CurrentTime <= pPerson->StartTime + pPerson->WorkTime)/ . 执行写操作printf("Writer %d is Exit.n",pPerson->ID);printf("nn*n");NumOfWriteRequest-;ReleaseSemaphore(WriteSemaphore,1,NULL);if(pPerson->ID = 6 ) finished = true;/所有的读写完成ExitThread(0);return 0;(七) 总结;本次的操作系统课程设计,收获还是很大的。读者写者问题是一个经典的多线程的问题,图书馆和网上都有很多资料,我也看了很多这方面的资料,应该说这个课程设计为我更加深入的研究开了一个很好的头。验收的老师是路强老师,他当时问我怎么保证window下p,v操作的原子性,说实在的,我一直研究的是我程序的算法和实现,还真没考虑过我用的底层API函数的具体特征这个问题,我武断的认为windows底层已经实现了原子性,他让我回去再查资料,下次再验收,还跟我讲了很多他的研究生研究的课题与p,v操作有关,p,v操作的原子性至关重要。我查了很多资料,还到csdn询问了一些技术牛,虽然windows的API没有明确说明WaitForSingleObject()(也就是windows的一种p操作)的原子性,但是在很多文献和高手的博客中,证实了该函数的原子性。所以说这次课程设计不仅锻炼了我代码实现的能力,也是开拓了我的思路和想问题的方向,以及对细节的注重,再次感谢我的指导老师们,他别是路强老师对我的启发。(八) 参考文献;计算机操作系统.西安电子科技大学出版社C+Primer. 人民邮电出版社

    注意事项

    本文(操作系统课程设计报告读者写着问题.doc)为本站会员(仙人指路1688)主动上传,三一办公仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一办公(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-2

    经营许可证:宁B2-20210002

    宁公网安备 64010402000987号

    三一办公
    收起
    展开