操作系统课设报告(共22页)_第1页
操作系统课设报告(共22页)_第2页
操作系统课设报告(共22页)_第3页
操作系统课设报告(共22页)_第4页
操作系统课设报告(共22页)_第5页
已阅读5页,还剩27页未读 继续免费阅读

下载本文档

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

文档简介

1、操作系统(co zu x tn)课程设计(2011/2012学年(xunin)第二学期(xuq)第20周)指导教师:XXX班级: 学号:姓名: 计算机操作系统(co zu x tn)A课程设计目 录 TOC o 1-3 h z u HYPERLINK l _Toc328719859 一、题目(tm): PAGEREF _Toc328719859 h 3 HYPERLINK l _Toc328719860 二、目的(md)和设计要求: PAGEREF _Toc328719860 h 3 HYPERLINK l _Toc328719861 (1)、目的: PAGEREF _Toc328719861

2、 h 3 HYPERLINK l _Toc328719862 (2)设计要求: PAGEREF _Toc328719862 h 3 HYPERLINK l _Toc328719863 三、设计思想或方法: PAGEREF _Toc328719863 h 3 HYPERLINK l _Toc328719864 1.读者优先 PAGEREF _Toc328719864 h 3 HYPERLINK l _Toc328719865 2.写者优先 PAGEREF _Toc328719865 h 4 HYPERLINK l _Toc328719866 3.退出程序 PAGEREF _Toc32871986

3、6 h 4 HYPERLINK l _Toc328719867 四、实现的功能说明(相关API函数说明): PAGEREF _Toc328719867 h 4 HYPERLINK l _Toc328719868 五、设计流程图: PAGEREF _Toc328719868 h 10 HYPERLINK l _Toc328719869 六、核心源程序代码和界面图: PAGEREF _Toc328719869 h 10 HYPERLINK l _Toc328719870 1、源程序代码 PAGEREF _Toc328719870 h 10 HYPERLINK l _Toc328719871 2、主

4、菜单界面: PAGEREF _Toc328719871 h 17 HYPERLINK l _Toc328719872 3、读者优先界面: PAGEREF _Toc328719872 h 17 HYPERLINK l _Toc328719873 4、写者优先界面: PAGEREF _Toc328719873 h 18 HYPERLINK l _Toc328719874 七、实验心得与体会: PAGEREF _Toc328719874 h 19一、题目(tm):读者(dzh)写者问题二、目的(md)和设计要求:(1)、目的: 理解读者写者问题的基本概念,读写操作限制; 掌握基于windows的多线

5、程编程的基本流程;实现读者优先和写者优先的调度算法;(2)设计要求:在windows 2000环境下,创建一个控制台进程,此进程包含n个线程。用这n个线程来表示n个读者或写者。每个线程按相应测试数据文件(后面有介绍)的要求进行读写操作。用信号量机制分别实现读者优先和写者优先的读者写者问题。读者写者问题的读写操作限制(包括读者优先和写者优先):读者优先/写者优先先来先服务,避免并发抢占1)写写互斥,即不能有两个写者同时进行写操作。2)读写互斥,即不能同时有一个线程在读,而另一个线程在写。3)读读允许,即可以有一个或多个读者在读。读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进

6、行读操作,则该读者可直接开始读操作。写者优先的附加限制:如果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。三、设计思想或方法:可以将所有读者和所有写者分别存于一个读者等待队列和一个写者等待队列中,每当读允许时,就从读者队列中释放一个或多个读者线程进行读操作;每当写允许时,就从写者队列中释放一个写者进行写操作。1.读者优先读者优先指的是除非有写者在写文件,否则读者不需要等待。所以可以用个整

7、型变量readcount记录当前的读者数目,用于确定是否需要释放正在等待的写者线程(当readcount=0时,表明所有的读者读完,需要释放写者等待队列中的一个写者)。每一个读者开始读文件时,必须修改readcount变量。因此需要一个互斥对象h_Mutex来实现对全局变量readcount修改时的互斥。另外(ln wi),为了实现写写互斥,需要增加一个临界区对象RP_Write。当写者发出写请求时,必须申请(shnqng)临界区对象的所有权。通过这种方法,也可以实现读写互斥、当readcount=1时(即第一个读者到来时),读者线程也必须申请(shnqng)临界区对象的所有权。当读者拥有临界

8、区的所有权时,写者阻塞在临界区对象RP_Write上。当写者拥有临界区的所有权时,第一个读者判断完“readcount= =1”后阻塞在write上,其余的读者由于等待对readcount的判断,阻塞在mutex上。2.写者优先写者优先指的是除非有读者在读文件,否则写者不需要等待,一旦有写者,则后续读者必须等待,唤醒时优先考虑写者。所以用一个整形变量writecount记录当前的写者数目,用于确定是否需要释放正在等待的读者线程(当writecount=0时,表明所有的写者写完,需要释放读者等待队列中的一个写者)。,每一个写者开始读文件时,必须修改writecount变量,因此需要一个互斥对象h

9、_Mutex2来实现对全局变量writecount修改时的互斥。另外需要一个整形变量readcount记录写者申请前的读者数目,用于确定是否需要释放正在等待的写者线程(当readcount=0时,表明所有的读者读完,需要释放写者等待队列中的一个写者,后续的读者线程继续等待)。每一个读者开始读文件时,必须修改readcount变量。因此需要一个互斥对象h_Mutex1来实现对全局变量readcount修改时的互斥。为了实现读-写互斥,需要增加一个临界区对象cs_Read。当读者发出读请求时,必须申请到临界区对象的所有权。通过这种方法,也可以实现写者来后续读者等待,当读者发出读请求时,等待队列中已

10、有一个写者在等待,则必须申请到临界区对象的所有权。另外,为了实现写-写互斥和读者先来写者等待,需要增加一个临界区对象cs_Write。写者优先和读者优先有相同之处,不同的地方在:一旦有一个写者到来时,应该尽快让写者进行写,如果有一个写者在等待,则新到的读者操作不能读操作,为此添加一个整型变量writecount,记录写者的数目,当writecount=0时才可以释放读者进行读操作!为了实现对全局变量writecount的互斥访问,设置了一个互斥对象Mutex3。为了实现写者优先,设置一个临界区对象read,当有写者在写或等待时,读者必须阻塞在临界区对象read上。读者除了要一个全局变量read

11、count实现操作上的互斥外,还需要一个互斥对象对阻塞在read这一个过程实现互斥,这两个互斥对象分别为mutex1和mutex2。3.退出程序选择退出程序后,按任意键即可结束程序。四、实现(shxin)的功能说明(相关(xinggun)API函数说明):1.CreateThread函数(hnsh)功能:该函数创建一个在调用进程的地址空间中执行的线程。函数原型:HANDLE CreateThread (LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress

12、,LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);参数:lpThreadAttributes:指向一个LPSECURITY_ATTRIBUTES结构。该结构决定了返回的句柄是否可被子进程继承。若lpThreadAttributes为NULL,则句柄不能被继承。在Windows NT中该结构的lpSecurityDescriptor成员定义了新进程的安全性描述符。若lpThreadAttributes为NULL。则线程获得个默认的安全性描述符。dwStackSize:定义原始堆栈提交时的大小(按字节计)。系统将该值舍入

13、为最近的页。若该值为0,或小于默认时提交的大小,默认情况是使用与调用线程同样的大小更多的信息,请看Thread Stack Size。lpStartAddress:指向一个LPTHREAD_START_ROUTINE类型的应用定义的函数,该线程执行此函数。该指针还表示远程进程中线程的起始地址。该函数必须存在于远程进程中。lpParameter:定义一个传递给该进程的32位值。dwCreationFlags:定义控制进程创建的附加标志。若定义了CREATE_SUSPENDED标志,线程创建时处于挂起状态,并且直到ResumeThread函数调用时才能运行。若该值为0,则该线程在创建后立即执行。l

14、pThreadId:指向个32位值,它接收该线程的标识符。返回值:若函数调用成功,返回值为新线程的句柄;若函数调用失败,返回值为NULL。备注:新进程的句柄创建时设为THREAD_ALL_ACCESS访问权限。若未提供安全性描述符,则该句柄可被任何要求一个线程对象句柄的函数所使用。若提供了安全性描述符,则以后使用该句柄时,将在授权访问以前执行访问检查。若访问检查拒绝访问,则请求进程不能使用该句柄获得对该线程的访问。线程从lpStartAddress参数定义的函数处开始执行。若该函数返回,系统将默认地认为以调用ExitThread函数的方法终止该线程。使用GetExitcodeThread函数来

15、获得线程的返回值。线程创建时拥有THREAD_PRIORITY_NORMAL优先权。使用GetThreadPriority和SetThreadPriority函数可以获得和设置线程的优先权值。一个线程终止时。该线程对象被设为发信号状态,以满足在该对象上等待的所有进程。一个线程对象始终存在于系统中,直到该线程终止,且它所有的句柄都已通过(tnggu)调用CloseHandle函数关闭。2.Sleep函数(hnsh)功能:该函数对于指定的时间(shjin)间隔挂起当能的执行线程。函数原型:VOID Sleep (DWORD dwMulliseconds);参数:dwMilliseconds:定义挂

16、起执行线程的时间,以毫秒(ms)为单位。取值为0时,该线程将余下的时间片交给处于就绪状态的同一优先级的其他线程。若没有处于就绪状态的同一优先级的其他线程,则函数立即返回,该线程继续执行。若取值为INFINITE则造成无限延迟。返回值:该函数没有返回值。备注:一个线程可以在调用该函数时将睡眠时间设为0ms,以将剩余的时间片交出。3.CreateMutex函数功能:该函数创建有名或者无名的互斥对象。函数原型:HANDLE CreateMutex (LPSECURITY_ATTRIBUTES lpMutexAttributes,BOOL bInitialOwner, LPCTSTR lpName);

17、参数:lpMutexAttributes:指向SECURITY_ATTRIBUTES结构的指针,该结构决定子进程是否能继承返回句柄。如果lpMutexAttributes为NULL,那么句柄不能被继承。在Windows NT中该结构的LpSecuriyDescriptor成员指定新互斥对象的安全描述符。如果lpMutexAttributes为NULL,那么互斥对象获得默认的安全描述符。bInitialOwner:指定互斥对象的初始所属身份。如果该值为TRUE,并且调用者创建互斥对象,那么调用线程获得互斥对象所属身份。否则,调用线程不能获得互斥对象所属身份。判断调用者是否创建互斥对象清参阅返回值

18、部分。lpName:指向以NULL结尾的字符串,该字符串指定了互斥对象名。该名字的长度小于MAX_PATH且可以包含除反斜线()路径分隔符以外的任何字符。名字是区分大小写的。如果lpName与已存在的有名互斥对象名相匹配,那么该函数要求用MUTEX_ALL_ACCESS权限访问已存在的对象。在这种情况下,由于参数bInitialOwner已被创建进程所设置,该参数被忽略。如果参数lpMutexAttributes不为NULL,它决定句柄是否解除继承,但是其安全描述符成员被忽略。如果lpName为NULL,那么创建的互斥对象无名。如果lpName与已存在的事件、信号量、可等待定时器、作业(zuy

19、)或者义件映射对象的名字相匹配,那么函数调用失败,并且 GetLastError函数返回ERROR_ALREADY_HANDLE,其原因是这些对象共享相同的名字空间。返回值:如果函数调用成功,返回值是互斥对象句柄;如果函数调用之前,有名(yu mng)互斥对象已存在,那么函数给已存在的对象返回一个句柄,并且函数GetLastError返回ERROR_ ALREADY_EXISTS。否则,调用者创建互斥对象。如果(rgu)函数调用失败,则返回值为NULL。若想获得更多错误信息,请调用GetLastError函数。备注:由函数CreateMutex返回的句柄有MUTEX_ALL_ACCESS权限可

20、以去访问新的互斥对象,并且可用在请求互斥对象句柄的任何函数中。调用进程中的任何线程可以在调用等待函数时指定互斥对象句柄。当指定对象的状态为信号态时。返回单对象等待函数。当任何一个或者所有的互斥对象都为信号态时,返回多对象等待函数指令。等待函数返回后,等待的线程被释放,继续向下执行。当一个互斥对象不被任何线程拥有时,处于信号态。创建该对象的线程可以使用bInitialOwner标志来请求立即获得对该互斥对象的所有权。否则,线程必须使用等待函数来请求所有权。当互斥对象处于信号态,等待的线程获得对该对象的所有权时,此互斥对象的状态被设置为非信号态,等待函数返回。任意时刻,仅有一个线程能拥有该互斥对象

21、线程可以使用ReleaseMutex函数来释放对这个互斥对象的所有权。总线程已经拥有了个互斥对象,那么它可以重复调用等待函数而不会发生阻塞,一般情况下,用户不会重复等待同一个互斥对象,这种机制防止了线程因等待它已经拥有的互斥对象而发生死锁。然而,线程必须为每一次等待调用次ReleaseMutex函数来释放该互斥对象。两个或多个进程可以调用CreateMutex来创建同名的互斥对象,第一个进程实际创建互斥对象以后的进程打开已存在的互斥对象的句柄。这使得多个进程可以得到同一个互斥对象的句柄,从而减轻了用户的负担,使用户不必判断创建进程是否为第一个启动的进程。使用这种技术时,应该把bInitialO

22、wner标志设为FALSE;否则很难确定开始时哪一个进程拥有该互斥对象。由于多进程能够拥有相同互斥对象的句柄,通过使用这个对象,可使多进程同步。以下为共享对象机制:如果CreateMutex中的lpMutexAttributes参数允许继承,由CreateProcess函数创建的子进程可以继承父近程的互斥对象句柄。一个进程可以在调用DuplicateHandle函数时指定互斥对象句柄来创建一个可以被其他进程使用的双重句柄。一个进程在调用OpenMutex或CreateMutex函数时能指定互斥对象名。使用CloseHandle函数关闭句柄,进程结束时系统自动关闭句柄。当最后一个句柄被关闭时,互

23、斥对象被销毁。4.ReleaseMutex函数(hnsh)功能:该函数放弃指定(zhdng)互斥对象的所有权。函数(hnsh)原型:BOOL ReleaseMutex (HANDLE hMutex);参数:hMutex:互斥对象句柄。为CreateMutex或OpenMutex函数的返回值。返回值:如果函数调用成功,那么返回值是非零值;如果函数调用失败,那么返回值是零值。若想获得更多错误信息,请调用GetLastError函数。备注:如果调用线程不拥有互斥对象,ReleaseMutex函数失败。一个线程通过调用等待函数拥有互斥对象。创建该互斥对象的线程也拥有互斥对象。而不需要调用等待函数。当互

24、斥对象的所有者线程不再需要互斥对象时,它可以调用ReleaseMutex函数。当个线程拥有个互斥对象后,它可以用该互斥对象多次调用等待函数而不会阻塞。这防止一个线程等待一个它已拥有的互斥对象时出现死锁。不过,为了释放所有权,该线程必须为每一个等待操作调用一次ReleaseMutex函数;5.WaitForSingleObject函数功能:当下列情况之一发生时该函数返回:(1)指定对象处于信号态;(2)超时。函数原型:DWORD WaitForSingleObject (HANDLE hHandle, DWORD dwMilliseconds);参数:hHandle:等待对象句柄。若想了解指定句

25、柄的对象类型列表,参阅下面备注部分。在WindowsNT中,句柄必须有SYNCHRONIZE访问权限。若想获得更多的信息,请查看Standard Access Rights。dwMilliseconds:指定以毫秒为单位的超时间隔。如果超时,即使对象的状态是非信号态的并且没有完成,函数也返回。如果dwMillseconds是0,函数测试对象的状态并立刻返回;如果dwMillseconds是INFINITE,函数从不超时。返回值:如果函数调用成功,返回值表明引起函数返回的事件。可能值如下:WAIT_ABANDONED:指定对象是互斥对象,在线程被终止前,线程没有释放互斥对象。互斥对象的所属关系被

26、授予调用线程,并且该互斥对象被置为非信号态。WAIT_OBJECT_0:指定对象的状态被置为信号态。WAIT_TIMEOUT:超时,并且对象的状态为非信号态。如果函数调用失败,返回值是WAIT_FAILED。若想获得更多错误信息,请调用GetLastError函数。备注:WaitForSingleObjects函数决定等待条件(tiojin)是否被满足。如果等待条件并没有被满足,调用线程进入个高效(o xio)的等待状态,当等待满足条件时占用非常少的处理器时间。在运行前。一个等待函数修改同步对象类型的状态。修改仅发生在引起函数返回的对象身上(shn shng)。例如,信号得计数减1。WaitF

27、orSingleObjects函数能等待的对象包括:Change notification(改变通告):Console input(控制台输入);Event(事件);Job(作业);Mutex(互斥对象);Process(进程);Semaphore(信号量);Thread(线程);Waitable timer (可等待定时器)。当使用等待函数或代码直接或间接创建窗口时,一定要小心。如果一个线程创建了任何窗口,它必须处理进程消息。消息广播被发送到系统的所有窗口。一个线程用没有超时的等待函数也许会引起系统死锁。间接创建窗口的两个例子是DDE和COM CoInitialize。因此,如果用户有一个创

28、建窗口的线程,用MsgWaitForMultipleObjects或MsgWaitForMultipleObjectEx函数,而不要用SignalObjectAndWait函数。6.WaitForMultipleObjects函数功能:WaitForMultipleObjects函数当下列条件之一满足时返回:(1)任意一个或全部指定对象处于信号态;(2)超时间隔已过。函数原型:DWORD WaitForMultipleObjects (DWORD nCount, CONST HANDLE *lpHandles,BOOL fWaitAll, DWORD dwMilliseconds);参数:nC

29、ount:指定由lpHandles所指向的数组中的句柄对象数目最大对象句柄数目MAXIMUM_WAIT_OBJECTS。lpHandles:指向对象句柄数组的指针。该数组可以包含不同类型对象的句柄。在WindowsNT中,该句柄必须有SYNCHRONIZE访问权限。若想获得更多的信息,请查看Standard Access Rights。fWaitAll:指定等待类型。如果为TRUE,当lpHandles指向的数组里的全部对象为信号态时,函数返回。如果为FALSE,当由lpHandles指向的数组里的任对象为信号态时,函数返回。对于后者,返回值指出引起函数返回的对象。dwMilliseconds

30、:指定以毫秒为单位的超时间隔。如果超时,即使bWaitAll参数指定的条件没有满足,函数也返回。如果dwMilliseconds是0,函数测试指定对象的状态并立刻返回。如果dwMilliseconds是INFINITE,函数从不超时。返回值;如果函数调用成功,返回值表明引起函数返回的事件。可能值如下:WAIT_OBJECT_0到WAIT_OB JECT0+ nCount-1:如果bWaitAll为TRUE,那么返回值表明所有指定对象的状态为信号态。如果bWaitAll为FALSE,那么返回值减去WAIT_OBJECT_0表明引起函数返回的对象的pHandles数组索引。如果多于一个对象变为信号

31、态,则返回的是数组索引最小的信号态对象索引。WAIT_ABANDONED_0到WAIT_ABANDONED_0+nCount-1:如果bWaitAll为TRUE,那么(n me)返回值表明所有指定对象的状态为信号态,并且至少一个对象是己放弃的互斥对象。如果bWaitAll为FALSE,那么返回值减去WAIT_ABANDONED_0表明引起函数返回的放弃互斥对象的pHandles数组索引。WAIT_TIMEOUT:超时并且由参数(cnsh)bWaitAll指定的条件没有满足。如果函数调用(dioyng)失败,返回值是WAIT_FAILED。若想获得更多错误信息,请调用GetLastError函数

32、。7.InitializeCriticalSection函数功能:该函数初始化临界区对象:函数原型:VOID InitializeCriticalSection (LPCRITIAL_SECTION lpCriticalSection);参数:lpCritialSection:指向临界区对象的指针。备注:单进程的所有线程可以使用互斥同步机制的临界区对象。但是,不能保证线程获得临界区所有权的顺序,系统将对所有线程公平处理。进程负责分配临界区对象使用的存储空间,这可以通过声明CRITICAL_SECTION类型的变量来完成。在使用临界区之前,该进程的一些线程必须使用InitializeCritic

33、alSection或InitializeCriticalSectionAndSpinCount函数来初始化该临界区对象。8.EnterCriticalSection函数功能:该函数是等待指定临界区对象的所有权。当调用线程被赋予所有权时,该函数返回。函数原型:VOID EnterCriticalSection (LPCRITICAL_SECTION lpCriticalSecrion);参数:lpCriticalSecrion:指间临界区对象的指针。9.LeaveCriticalSection函数功能:该函数释放指定临界区对象的所有权。函数原型:VOID LeaveCriticalSection

34、 (LPCRITICAL_SECTION lpCriticalSection);参数;lpCriticalSecrion:指向临界区对象的指针。五、设计(shj)流程图: 图1:读者(dzh)优先流程图图2:写者优先流程图六、核心(hxn)源程序代码和界面图:1、源程序代码#include windows.h#include #include #include #include #include #include #define READER R /读者#define WRITER W /写者#define INTE_PER_SEC 500 /每秒时钟中断的数目#define MAX_THRE

35、AD_NUM 64 /最大线程数#define MAX_FILE_NUM 32 /最大文件数目数#define MAX_STR_LEN 32 /字符串的长度int readcount=0; /读者数目int writecount=0; /写者数目(shm)CRITICAL_SECTION RP_Write; /临界(ln ji)资源CRITICAL_SECTION cs_Write;CRITICAL_SECTION cs_Read;struct ThreadInfo int serial; /线程序(chngx)号 char entity; /线程类别(判断是读者还是写者线程) double

36、delay; /线程延迟时间 double persist; /线程读写操作时间;/ 读者优先读者线程/P:读者线程信息void RP_ReaderThread(void *p) /互斥变量 HANDLE h_Mutex; h_Mutex=OpenMutex(MUTEX_ALL_ACCESS,FALSE,mutex_for_readcount); DWORD wait_for_mutex; /等待互斥变量所有权 DWORD m_delay; /延迟时间 DWORD m_persist; /读文件持续时间 int m_serial; /线程序号 / 从参数中获得信息 m_serial=(Thre

37、adInfo*)(p)-serial ; m_delay=(DWORD)(ThreadInfo*)(p)-delay *INTE_PER_SEC); m_persist=(DWORD)(ThreadInfo*)(p)-persist *INTE_PER_SEC); Sleep(m_delay); /延迟等待 printf(Reader thread %d sents the reading require.n,m_serial); /等待互斥信号,保证对ReadCount 的访问,修改互斥 wait_for_mutex=WaitForSingleObject(h_Mutex,-1); /读者数

38、目增加 readcount+; if(readcount=1) /第一个读者,等待资源 EnterCriticalSection(&RP_Write); ReleaseMutex(h_Mutex); /释放互斥信号 /读文件 printf(Reader thread %d begins to read file.n,m_serial); Sleep(m_persist); /退出线程 printf(Reader thread %d finished reading file.n,m_serial); /等待互斥信号,保证对ReadCount的访问(fngwn),修改互斥 wait_for_mu

39、tex=WaitForSingleObject(h_Mutex,-1); /读者数目(shm)减少 readcount-; if(readcount=0) /如果(rgu)所有的读者读完,唤醒写者 LeaveCriticalSection(&RP_Write); ReleaseMutex(h_Mutex); /释放互斥信号/P:写者线程信息void RP_WriterThread(void *p) DWORD m_delay; /延迟时间 DWORD m_persist; /写文件持续时间 int m_serial; /线程序号 / 从参数中获得信息 m_serial=(ThreadInfo*

40、)(p)-serial ; m_delay=(DWORD)(ThreadInfo*)(p)-delay *INTE_PER_SEC); m_persist=(DWORD)(ThreadInfo*)(p)-persist *INTE_PER_SEC); Sleep(m_delay); printf(Writer thread %d sents the writing require.n,m_serial); /等待资源 EnterCriticalSection(&RP_Write);/实现写-写互斥 /写文件 printf(Writer thread %d begins to write to

41、the file.n,m_serial); Sleep(m_persist); /退出线程 printf(Writer thread %d finished writing to the file.n,m_serial); /释放资源 LeaveCriticalSection(&RP_Write);/读者优先处理函数/file:文件名void ReaderPriority(char *file) DWORD n_thread=0; /线程数目 DWORD thread_ID; /线程ID DWORD wait_for_all; /等待所有线程结束 /线程对象的数组 HANDLE h_Threa

42、dMAX_THREAD_NUM; ThreadInfo thread_infoMAX_THREAD_NUM; readcount=0; /初始化readcount InitializeCriticalSection(&RP_Write); /初始化临界(ln ji)区 ifstream inFile; inFile.open (file); printf(Reader Priority:nn); while(inFile) /读入每一个读者(dzh),写者的信息 inFilethread_infon_thread.serial; inFilethread_infon_thread.entity

43、; inFilethread_infon_thread.delay; inFilethread_infon_thread+.persist; inFile.get(); for(int i=0;iserial ; m_delay=(DWORD)(ThreadInfo*)(p)-delay *INTE_PER_SEC); m_persist=(DWORD)(ThreadInfo*)(p)-persist *INTE_PER_SEC); Sleep(m_delay); /延迟等待 printf(Reader thread %d sents the reading require.n,m_seria

44、l); wait_for_mutex1=WaitForSingleObject(h_Mutex1,-1); /读者进去临界区 EnterCriticalSection(&cs_Read);/读者先来,一旦有写者,则后续读者必须等待,唤醒时优先考虑写者 /阻塞互斥对象Mutex2,保证对readCount的访问和修改互斥 wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1); /修改读者的数目 readcount+; if(readcount=1) / 如果是第1个写,等待读者写完 EnterCriticalSection(&cs_Write); Re

45、leaseMutex(h_Mutex2);/ 释放互斥信号 Mutex2 /让其他读者进去临界区 LeaveCriticalSection(&cs_Read); ReleaseMutex(h_Mutex1); /读文件 printf(Reader thread %d begins to read file.n,m_serial); Sleep(m_persist); /退出线程 printf(Reader thread %d finished reading file.n,m_serial); /阻塞互斥对象Mutex2,保证对readcount的访问,修改互斥 wait_for_mutex2

46、=WaitForSingleObject(h_Mutex2,-1); readcount-; if(readcount=0) /最后一个读者(dzh),唤醒写者 LeaveCriticalSection(&cs_Write); ReleaseMutex(h_Mutex2); /释放(shfng)互斥信号/写者优先(yuxin)写者线程/P:写者线程信息void WP_WriterThread(void *p) DWORD wait_for_mutex2; /互斥变量 DWORD m_delay; /延迟时间 DWORD m_persist; /读文件持续时间 int m_serial; /线程

47、序号 HANDLE h_Mutex2;/互斥对象h_Mutex2来实现对全局变量writecount修改时的互斥 h_Mutex2=OpenMutex(MUTEX_ALL_ACCESS,FALSE,mutex2); /从参数中获得信息 m_serial=(ThreadInfo*)(p)-serial ; m_delay=(DWORD)(ThreadInfo*)(p)-delay *INTE_PER_SEC); m_persist=(DWORD)(ThreadInfo*)(p)-persist *INTE_PER_SEC); Sleep(m_delay); /延迟等待 printf(Writer

48、 thread %d sents the writing require.n,m_serial); wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1); writecount+; /修改写者数目 if(writecount=1) EnterCriticalSection(&cs_Read);/控制读写互斥,读者等待写者释放资源 ReleaseMutex(h_Mutex2); EnterCriticalSection(&cs_Write);/有写者在写,写者等待 printf(Writer thread %d begins to write to t

49、he file.n,m_serial); Sleep(m_persist); printf(Writer thread %d finished writing to the file.n,m_serial); LeaveCriticalSection(&cs_Write); wait_for_mutex2=WaitForSingleObject(h_Mutex2,-1); writecount-; if(writecount=0) LeaveCriticalSection(&cs_Read); ReleaseMutex(h_Mutex2);/写者优先(yuxin)处理函数/ file:文件名v

50、oid WriterPriority(char * file) DWORD n_thread=0; DWORD thread_ID; DWORD wait_for_all; HANDLE h_ThreadMAX_THREAD_NUM; ThreadInfo thread_infoMAX_THREAD_NUM; readcount=0; writecount=0; InitializeCriticalSection(&cs_Write);/写写互斥的临界(ln ji)区 InitializeCriticalSection(&cs_Read);/读写互斥的临界(ln ji)区 ifstream i

51、nFile; inFile.open (file); printf(Writer priority:nn); while(inFile) inFilethread_infon_thread.serial; inFilethread_infon_thread.entity; inFilethread_infon_thread.delay; inFilethread_infon_thread+.persist; inFile.get(); for(int i=0;i(int)(n_thread);i+) if(thread_infoi.entity=READER|thread_infoi.enti

52、ty =r) /创建读者进程 h_Threadi=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_ReaderThread),&thread_infoi,0,&thread_ID); else /创建写线程 h_Threadi=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)(WP_WriterThread),&thread_infoi,0,&thread_ID); /等待所有的线程结束 wait_for_all=WaitForMultipleObjects(n_thread,h_Thread,TRUE,-

53、1); printf(All reader and writer have finished operating.n);/主函数(hnsh)int main(int argc,char *argv) char ch; while(true) printf(*n); printf( 1.Reader Priorityn); printf( 2.Writer Priorityn); printf( 3.Exit to Windowsn); printf(*n); printf(Enter your choice(1,2,3): ); do ch=(char)_getch(); while(ch!=

54、1&ch!=2&ch!=3); system(cls); if(ch=3) return 0; else if(ch=1) ReaderPriority(thread.dat); else WriterPriority(thread.dat); printf(nPress Any Key to Coutinue:); _getch(); system(cls); return 0;2、主菜单(ci dn)界面:对数据文件thread.dat进行(jnxng)分析:1 W 3 52 W 4 53 R 5 24 R 6 55 W 5.1 33、读者(dzh)优先界面:分析(fnx)如下:Write

55、r thread 1 sents the writing require.Writer thread 1 begins to write to the file.当写者1发出请求时,没有(mi yu)读者,写者1写文件。Writer thread 2 sents the writing require.当写者2发出请求时,有写者在写,写者2阻塞。Reader thread 3 sents the reading require.当读者3发出请求时,有写者在写,读者3阻塞。Writer thread 5 sents the writing require.Reader thread 4 sents the reading require.Reader thread 4 begins to read file.应写者1完成写文

温馨提示

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

评论

0/150

提交评论