操作系统实验读者写者.ppt_第1页
操作系统实验读者写者.ppt_第2页
操作系统实验读者写者.ppt_第3页
操作系统实验读者写者.ppt_第4页
操作系统实验读者写者.ppt_第5页
已阅读5页,还剩25页未读 继续免费阅读

下载本文档

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

文档简介

计算机操作系统原理实验,实验二:读者写者问题 指 导:蒋良宵 邮 箱:operating_,1,概 述,实验目的 实验内容 实验要求 实验环境 实验分析与设计 相关API函数 输入数据与运行结果说明,2,对读者写者问题的实现进行分析,并进一步分别对读者优先和写者优先两种算法的核心思想作了探讨和程序设计的提示。,对程序设计中将会用到的API函数的功能及参数进行说明,并对其中重要的几个函数作讲解。,实验目的,1、熟悉多线程编程 2、熟悉使用信号量机制解决同步问题,3,实验内容,创建一个控制台进程。 此进程包含n个线程。 用这n个线程来表示n个读者或写者。 每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。 用信号量机制分别实现读者优先和写者优先的读者-写者问题。,4,实验要求,读者-写者问题的读写操作限制(包括读者优先和写者优先):,1) 写-写互斥,即不能有两个写者同时进行写操作。,2) 读-写互斥,即不能同时有一个线程在读,而另一个线程在写。,3) 读-读允许,即可以有一个或多个读者在读。,比喻:把摘花比作写,赏花比作读,那么写-写互斥就像两个或多个人不能同时摘同一朵花,否则就出现争抢场面。,类似的,那么读-写互斥就像一个人正在赏花时,另一个人却在摘这朵花,导致矛盾的产生。,不同的是,对于一朵花而言,多个人可以同时观赏,并不会产生矛盾。,5,实验要求(续),读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。,写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。,运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。,6,实验环境,1、一台WINDOWS 2000/NT/XP操作系统的计算机 2、Visual C+编程平台,7,实验分析与设计进程和线程(1/2),在Windows32位操作系统中,所谓多任务是指系统可以同时运行多个进程,而每个进程也可以同时执行多个线程。 所谓进程就是应用程序的运行实例。每个进程都有自己私有的虚拟地址空间。每个进程都有一个主线程,但可以建立另外的线程。进程中的线程是并发执行的,每个线程占用CPU的时间由系统来划分。我们可以把线程看成是操作系统分配CPU时间的基本实体。,8,实验分析与设计进程和线程(2/2),进程中的所有线程共享进程的虚拟地址空间,这意味着所有线程都可以访问进程的全局变量和资源。这一方面为编程带来了方便,但另一方面也容易造成冲突。 虽然在进程中进行费时的工作不会导致系统的挂起,但这会导致进程本身的挂起。所以,如果进程既要进行长期的工作,又要响应用户的输入,那么它可以启动一个线程来专门负责费时的工作,而主线程仍然可以与用户进行交互。,9,实验分析与设计线程同步(1/3),1、线程的同步 多线程的使用会产生一些新的问题,主要是如何保证线程的同步执行。多线程应用程序需要使用同步对象和等待函数来实现同步。同步问题是实现远程数据采集或远程自动控制编程中的关键技术问题。,10,实验分析与设计线程同步(2/3),2、同步的原因 由于同一进程的所有线程共享进程的虚拟地址空间,并且线程的中断是汇编语言级的,所以可能会发生两个线程同时访问同一个对象(包括全局变量、共享资源、API 函数和MFC对象等)的情况,这有可能导致程序错误。例如,如果一个线程在未完成对某一大尺寸全局变量的读操作时,另一个线程又对该变量进行了写操作,那么第一个线程读入的变量值可能是一种修改过程中的不稳定值。 属于不同进程的线程在同时访问同一内存区域或共享资源时,也会存在同样的问题。因此,在多线程应用程序中,常常需要采取一些措施来同步线程的执行。,11,实验分析与设计线程同步(3/3),3、同步的方法 由于线程间需要同步机制,才能协调运行。在Win32 编程中,主要由WINDOWS API函数来实现,这部分知识将会在后面讨论。,12,实验分析与设计同步对象(1/4),同步对象用来协调多线程的执行,它可以被多个线程共享。线程的 等待函数用同步对象的句柄作为参数,同步对象应该是所有要使用 的线程都能访问到的。同步对象的状态要么是有信号的,要么是无 信号的。同步对象主要有三种:事件、mutex 和信号灯。,13,实验分析与设计同步对象(2/4),事件对象(Event)是最简单的同步对象,它包括有信号和无信号两种状态。在线程访问某一资源之前,也许需要等待某一事件的发生,这时用事件对象最合适。例如,只有在通信端口缓冲区收到数据后,监视线程才被激活。,14,Mutex 对象的状态在它不被任何线程拥有时是有信号的,而当它被拥有时则是无信号的。mutex 对象很适合用来协调多个线程对共享资源的互斥访问(mutually exclusive)。,15,实验分析与设计同步对象(4/4),信号灯对象维护一个从 0 开始的计数,在计数值大于 0 时对象是有信号的,而在计数值为 0 时则是无信号的。信号灯对象可用来限制对共享资源进行访问的线程数量。线程用CreateSemaphore函数来建立信号灯对象,在调用该函数时,可以指定对象的初始计数和最大计数。在建立信号灯时也可以为对象起个名字,别的进程中的线程可以用OpenSemaphore函数打开指定名字的信号灯句柄。,16,实验分析与设计临界区,临界区 (Critical Seciton) 与 mutex 的功能类似,但它只能由同一进程中的线程使用。临界区可以防止共享资源被同时访问。 进程负责为临界区分配内存空间,临界区实际上是一个CRITICAL_SECTION型的变量,它一次只能被一个线程拥有。在线程使用临界区之前,必须调用 InitializeCriticalSection 函数将其初始化。如果线程中有一段临界的代码不希望被别的线程中断,那么可以调用 EnterCriticalSection 函数来申请临界区的所有权,在运行完临界代码后再用LeaveCriticalSection 函数来释放所有权。如果在调用EnterCriticalSection 时临界区对象已被另一个线程拥有,那么该函数将无限期等待所有权。,17,实验分析与设计分析(1/3),由题目要求可以知道,这是一个实现多线程的使用,要求多个读者线程和多个写者线程共享读写临界区,而各个读者线程共享读进程资源,各个写线程共享写进程资源,所以这里包含了两个层次的共享,不妨把读写线程共享的临界区称为全局临界区,所有读线程共享的读进程的临界资源称为局部读临界区,所有写线程共享的写进程的临界资源称为局部写临界区。具体的关系如图所示:,18,实验分析与设计分析(2/3),19,读写线程共 享的内存读 写临界区,读进程 共享资源,写进程 共享资源,读线程1,读线程2,读线程3,写线程1,写线程2,写线程3,实验分析与设计分析(3/3),根据题目的要求还可以知道,在一个进程下的多个线程的并发情况:同是读进程的不同线程可以同时访问读写全局临界区,但是同是写进程的不同线程每次只能一个访问该读写全局临界区,还有就是读写线程不能同时访问读写全局临界区。,20,实验分析与设计设计,21,根据以上的进程和线程的理解以及对线程同步机制的分析,结合本次实验的特点,设计出了以下的方案: 读线程间和写线程间对各自局部共享资源的访问修改采用Mutex 对象,结合WaitForSingleObject 保证互斥操作。 读线程与写线程争用全局临界资源采用临界区(Critical Seciton)。 统管读写线程的线程采用WaitForMultipleObjects 保证等待所有 的线程结束。,相关API函数等待函数(1/2),22,等待函数只有在作为其参数的一个或多个同步对象产生信号时才会返回。在超过规定的等待时间后,不管有无信号,函数也都会返回。在等待函数未返回时,线程处于等待状态,此时线程只消耗很少的CPU时间。使用等待函数即可以保证线程的同步,又可以提高程序的运行效率。,DWORD WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds);,参数 hHandle 是同步对象的句柄。参数dwMilliseconds 是以毫秒为单位的超时间隔,如果该参数为0,那么函数就测试同步对象的状态并立即返回,如果该参数为INFINITE,则超时间隔是无限的。,相关API函数等待函数(2/2),23,DWORD WaitForMultipleObjects (DWORD nCount, CONST HANDLE * lpHandles, BOOL fWaitAll, IDWORD dwMilliSeconds) ;,函数功能:WaiForMultipleObjects函数当下列条件之一满足时返回:(1)任意一个或全部指定对象处于信号态;(2)超时间隔已过。 返回值:如果函数调用成功,返回值表明引起函数返回的事件。,注:该函数及后面的函数介绍中皆省略了对参数的介绍,请参考 文档。,相关API函数其他函数(1/4),24,HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter,DWORD dwCreationFlag, LPDWORD lpThreadId);,函数功能:该函数创建一个在调用进程的地址空间中执行的线程。 返回值:若函数调用成功,返回值为新线程的句柄;若函数调用失败,返回值为NULL。,相关API函数其他函数(2/4),25,VOID ExitThread (DWORD dwExitCode); 函数功能:该函数结束一个线程。 返回值:无。,VOID Sleep (DWORD dwMilliseconds); 函数功能:该函数对于指定的时间间隔挂起当前的执行线程。 返回值:该函数没有返回值。,相关API函数其他函数(3/4),26,HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner,LPCTSTR lpName); 函数功能:该函数创建有名或者无名的互斥对象。 返回值:如果函数调用成功,返回值是互斥对象句柄;如果函数调用之前,有名互斥对象已存在,那么函数给已存在的对象返回一个句柄,并且函数GetLastError返回ERROR_ALREADY_EXISTS,否则,调用者创建互斥对象。,Bool ReleaseMutex (HANDLE hMutex); 函数功能:该函数放弃指定互斥对象的所有权。 返回值:如果函数调用成功,那么返回值是非零值;如果函数调用失败,那么返回值是零值。若想获得更多错误信息,请调用GetLastError函数。,相关API函数其他函数(4/4),27,VOID InltlalizeCriticalSection(LPCRITICAL_SECTION IpCritiCalSection); 函数功能:该函数初始化临界区对象。 返回值:无。 VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 函数功能:该函数是等待指定临界区对象的所有权。当调用线程被 赋予所有权时,该函数返回。 返回值:无。 VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 函数功能:该函数释放指定临界区对象的所有权。 返回值:无。,数据输入格式,28,测试数据文件包括n行测试数据,分别描述创建的n个线程是读者还是写者,以及读写操作的开始时间和持续时间。每行测试数据包括四个字段,各个字段间用空格分隔。 第一字段为一个正整数,表示线程序号。 第二字段表示相应线程角色,R表示读者,W表

温馨提示

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

评论

0/150

提交评论