2022年操作系统学习课程设计方案 .pdf
《2022年操作系统学习课程设计方案 .pdf》由会员分享,可在线阅读,更多相关《2022年操作系统学习课程设计方案 .pdf(17页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、操作系统课程设计读者写者问题一、实习要求在 windows 2000 环境下,创建一个控制台进程,此进程包含n 个线程。用这n 个线程来表示n 个读者或写者。每个线程按相应测试数据文件(后面有介绍 )的要求进行读写操作。用信号量机制分别实现读者优先和写者优先的读者写者问题。读者写者问题的读写操作限制(包括读者优先和写者优先):1)写写互斥,即不能有两个写者同时进行写操作。2)读写互斥,即不能同时有一个线程在读,而另一个线程在写。3)读读允许,即可以有一个或多个读者在读。读者优先的附加限制:如果一个读者申请进行读操作时已有另一个读者正在进行读操作,则该读者可直接开始读操作。写者优先的附加限制:如
2、果一个读者申请进行读操作时已有另一写者在等待访问共享资源,则该读者必须等到没有写者处于等待状态后才能开始读操作。运行结果显示要求:要求在每个线程创建、发出读写操作申请、开始读写操作和结束读写操作时分别显示一行提示信息,以确定所有处理都遵守相应的读写操作限制。二、测试数据文件格式测试数据文件包括n 行测试数据,分别描述创建的n 个线程是读者还是写者,以及读写操作的开始时间和持续时间。每行测试数据包括四个字段,各个字段间用空格分隔。第字段为个正整数,表示线程序号。第二字段表示相应线程角色,R 表示读者, W 表示写者。第三字段为一个正数,表示读写操作的开始时间:线程创建后,延迟相应时间(单位为秒
3、)后发出对共享资源的读写申请。第四字段为一个正数,表示读写操作的持续时间。当线程读写申请成功后,开始对共享资源的读写操作,该操作持续相应时间后结束,并释放共享资源。下面是个测试数据文件的例子:1 R 3 5 2 W 4 5 3 R 5 2 4 R 6 5 5 W 5.1 3 注意 在创建数据文件时,由于涉及到文件格式问题,最好在记事本中手工逐个键入数据,而不要拷贝粘贴数据,否则,本示例程序运行时可能会出现不可预知的错误。三、实习分析可以将所有读者和所有写者分别存于一个读者等待队列和一个写者等待队列中,每当读允许时,就从读者队列中释放一个或多个读者线程进行读操作;每当写允许时,就从写者队列中释放
4、一个写者进行写操作。1.读者优先读者优先指的是除非有写者在写文件,否则读者不需要等待。所以可以用个整型变量readcount 记录当前的读者数目,用于确定是否需要释放正在等待的写者线程(当 readcount=0 时,表明所有的读者读完,需要释放写者等待队列中的一个写者)。每一个读者开始读文件时,必须修改readcount 变量。因此需要一个互斥对象mutex 来实现对全局变量readcount修改时的互斥。另外,为了实现写写互斥,需要增加一个临界区对象RP_Write 。当写者发出写请求时,必须申请临界区对象的所有权。通过这种方法,也可以实现读写互斥、当readcount=1 时(即第一个读
5、者到来时),读者线程也必须申请临界区对象的所有权。当读者拥有临界区的所有权时,写者阻塞在临界区对象RP_Write 上。当写者拥有临界区的所有权时,第一个读者判断完“readcount= =1”后阻塞在write 上,其余的读者由于等待对readcount的判断,阻塞在mutex上。精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 1 页,共 17 页2.写者优先(请根据自己编写的写者优先程序进行分析)四、相关API 函数说明1.CreateThread 函数功能:该函数创建一个在调用进程的地址空间中执行的线程。函数原型:HANDLE CreateT
6、hread (LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)。参数: lpThreadAttributes :指向一个LPSECURITY_A TTRIBUTES结构。该结构决定了返回的句柄是否可被子进程继承。若lpThreadAttributes 为 NULL ,则句柄不能被继承。在 Windows NT 中该结构的l
7、pSecurityDescriptor 成员定义了新进程的安全性描述符。若lpThreadAttributes为 NULL 。则线程获得个默认的安全性描述符。 dwStackSize:定义原始堆栈提交时的大小(按字节计 )。系统将该值舍入为最近的页。若该值为0,或小于默认时提交的大小,默认情况是使用与调用线程同样的大小更多的信息,请看Thread Stack Size。 lpStartAddress:指向一个LPTHREAD_START_ROUTINE类型的应用定义的函数,该线程执行此函数。该指针还表示远程进程中线程的起始地址。该函数必须存在于远程进程中。 lpParameter :定义一个传
8、递给该进程的32 位值。 dwCreationFlags:定义控制进程创建的附加标志。若定义了CREATE_SUSPENDED 标志,线程创建时处于挂起状态,并且直到ResumeThread函数调用时才能运行。若该值为0,则该线程在创建后立即执行。 lpThreadId :指向个32 位值,它接收该线程的标识符。返回值:若函数调用成功,返回值为新线程的句柄;若函数调用失败,返回值为NULL 。备注:新进程的句柄创建时设为THREAD_ALL_ACCESS访问权限。若未提供安全性描述符,则该句柄可被任何要求一个线程对象句柄的函数所使用。若提供了安全性描述符,则以后使用该句柄时,将在授权访问以前执
9、行访问检查。若访问检查拒绝访问,则请求进程不能使用该句柄获得对该线程的访问。线程从 lpStartAddress 参数定义的函数处开始执行。若该函数返回,系统将默认地认为以调用ExitThread 函数的方法终止该线程。使用GetExitcodeThread 函数来获得线程的返回值。线程创建时拥有THREAD_PRIORITY_NORMAL优先权。使用GetThreadPriority 和 SetThreadPriority 函数可以获得和设置线程的优先权值。一个线程终止时。该线程对象被设为发信号状态,以满足在该对象上等待的所有进程。一个线程对象始终存在于系统中,直到该线程终止,且它所有的句柄
10、都已通过调用CloseHandle 函数关闭。2.ExitThread 函数功能:该函数结束一个线程。函数原型:VOID ExitThread (DWORD dwExitCode );参数: dwExitCode :定义调用线程的退出代码。使用GetExitCodeThread 函数来检测一个线程的退出代码。返回值: 无。备注:调用 ExitThread 函数,是结束个线程的较好的方法。调用该函数后(或者直接地调用,或者从一个线程过精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 2 页,共 17 页程返回 ),当前线程的堆栈取消分配,线程终止。若调
11、用该函数时,该线程为进程的最后一个线程,则该线程的进程也被终止。线程对象的状态变为发信号状态,以释放所有正在等待该线程终止的其他线程。线程的终止状态从STILL_ACTIV ATE 变为 dwExitCode 参数的值。线程结束时不必从操作系统中移去该线程对象。当线程的最后一个句柄关闭时,该线程对象被删除。3.Sleep 函数功能:该函数对于指定的时间间隔挂起当能的执行线程。函数原型:VOID Sleep (DWORD dwMulliseconds);参数: dwMilliseconds:定义挂起执行线程的时间,以毫秒(ms)为单位。取值为0 时,该线程将余下的时间片交给处于就绪状态的同一优先
12、级的其他线程。若没有处于就绪状态的同一优先级的其他线程,则函数立即返回,该线程继续执行。若取值为INFINITE 则造成无限延迟。返回值:该函数没有返回值。备注:一个线程可以在调用该函数时将睡眠时间设为0ms,以将剩余的时间片交出。4.CreateMutex 函数功能:该函数创建有名或者无名的互斥对象。函数原型:HANDLE CreateMutex (LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName)。参数: lpMutexAttributes :指向 SECURITY_ATTRIBUTES结
13、构的指针,该结构决定子进程是否能继承返回句柄。如果lpMutexAttributes为 NULL ,那么句柄不能被继承。在 Windows NT 中该结构的LpSecuriyDescriptor 成员指定新互斥对象的安全描述符。如果lpMutexAttributes为 NULL ,那么互斥对象获得默认的安全描述符。 bInitialOwner :指定互斥对象的初始所属身份。如果该值为TRUE ,并且调用者创建互斥对象,那么调用线程获得互斥对象所属身份。否则,调用线程不能获得互斥对象所属身份。判断调用者是否创建互斥对象清参阅返回值部分。 lpName: 指向以 NULL 结尾的字符串,该字符串指
14、定了互斥对象名。该名字的长度小于MAX_PATH 且可以包含除反斜线()路径分隔符以外的任何字符。名字是区分大小写的。如果 lpName 与已存在的有名互斥对象名相匹配,那么该函数要求用MUTEX_ALL_ACCESS权限访问已存在的对象。在这种情况下,由于参数bInitialOwner 已被创建进程所设置,该参数被忽略。如果参数lpMutexAttributes不为 NULL ,它决定句柄是否解除继承,但是其安全描述符成员被忽略。如果 lpName 为 NULL ,那么创建的互斥对象无名。如果 lpName 与已存在的事件、信号量、可等待定时器、作业或者义件映射对象的名字相匹配,那么函数调用
15、失败,并且 GetLastError 函数返回ERROR_ALREADY_HANDLE,其原因是这些对象共享相同的名字空间。返回值:如果函数调用成功,返回值是互斥对象句柄;如果函数调用之前,有名互斥对象已存在,那么函数给已存在的对象返回一个句柄,并且函数GetLastError 返回 ERROR_ ALREADY_EXISTS。否则,调用者创建互斥对象。如果函数调用失败,则返回值为NULL 。若想获得更多错误信息,请调用GetLastError 函数。备注:精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 3 页,共 17 页由函数 CreateMu
16、tex 返回的句柄有MUTEX_ALL_ACCESS权限可以去访问新的互斥对象,并且可用在请求互斥对象句柄的任何函数中。调用进程中的任何线程可以在调用等待函数时指定互斥对象句柄。当指定对象的状态为信号态时。返回单对象等待函数。当任何一个或者所有的互斥对象都为信号态时,返回多对象等待函数指令。等待函数返回后,等待的线程被释放,继续向下执行。当一个互斥对象不被任何线程拥有时,处于信号态。创建该对象的线程可以使用bInitialOwner 标志来请求立即获得对该互斥对象的所有权。否则,线程必须使用等待函数来请求所有权。当互斥对象处于信号态,等待的线程获得对该对象的所有权时,此互斥对象的状态被设置为非
17、信号态,等待函数返回。任意时刻,仅有一个线程能拥有该互斥对象线程可以使用ReleaseMutex 函数来释放对这个互斥对象的所有权。总线程已经拥有了个互斥对象,那么它可以重复调用等待函数而不会发生阻塞,一般情况下,用户不会重复等待同一个互斥对象,这种机制防止了线程因等待它已经拥有的互斥对象而发生死锁。然而,线程必须为每一次等待调用次ReleaseMutex 函数来释放该互斥对象。两个或多个进程可以调用CreateMutex 来创建同名的互斥对象,第一个进程实际创建互斥对象以后的进程打开已存在的互斥对象的句柄。这使得多个进程可以得到同一个互斥对象的句柄,从而减轻了用户的负担,使用户不必判断创建进
18、程是否为第一个启动的进程。使用这种技术时,应该把bInitialOwner 标志设为FALSE;否则很难确定开始时哪一个进程拥有该互斥对象。由于多进程能够拥有相同互斥对象的句柄,通过使用这个对象,可使多进程同步。以下为共享对象机制: 如果 CreateMutex 中的 lpMutexAttributes参数允许继承,由CreateProcess函数创建的子进程可以继承父近程的互斥对象句柄。 一个进程可以在调用DuplicateHandle 函数时指定互斥对象句柄来创建一个可以被其他进程使用的双重句柄。一个进程在调用OpenMutex 或 CreateMutex 函数时能指定互斥对象名。 使用
19、CloseHandle 函数关闭句柄,进程结束时系统自动关闭句柄。当最后一个句柄被关闭时,互斥对象被销毁。5.ReleaseMutex 函数功能:该函数放弃指定互斥对象的所有权。函数原型:BOOL ReleaseMutex (HANDLE hMutex );参数: hMutex :互斥对象句柄。为CreateMutex 或 OpenMutex 函数的返回值。返回值:如果函数调用成功,那么返回值是非零值;如果函数调用失败,那么返回值是零值。若想获得更多错误信息,请调用GetLastError 函数。备注:如果调用线程不拥有互斥对象,ReleaseMutex 函数失败。一个线程通过调用等待函数拥有
20、互斥对象。创建该互斥对象的线程也拥有互斥对象。而不需要调用等待函数。当互斥对象的所有者线程不再需要互斥对象时,它可以调用ReleaseMutex 函数。当个线程拥有个互斥对象后,它可以用该互斥对象多次调用等待函数而不会阻塞。这防止一个线程等待一个它已拥有的互斥对象时出现死锁。不过,为了释放所有权,该线程必须为每一个等待操作调用一次ReleaseMutex 函数;6.WaitForSingleObject 函数功能:当下列情况之一发生时该函数返回:(1)指定对象处于信号态;(2)超时。函数原型:DWORD WaitForSingleObject (HANDLE hHandle, DWORD dw
21、Milliseconds)。参数:精选学习资料 - - - - - - - - - 名师归纳总结 - - - - - - -第 4 页,共 17 页 hHandle:等待对象句柄。若想了解指定句柄的对象类型列表,参阅下面备注部分。在 WindowsNT 中,句柄必须有SYNCHRONIZE访问权限。若想获得更多的信息,请查看Standard Access Rights。 dwMilliseconds:指定以毫秒为单位的超时间隔。如果超时,即使对象的状态是非信号态的并且没有完成,函数也返回。如果dwMillseconds 是 0,函数测试对象的状态并立刻返回;如果dwMillseconds 是I
22、NFINITE ,函数从不超时。返回值:如果函数调用成功,返回值表明引起函数返回的事件。可能值如下:WAIT_ABANDONED:指定对象是互斥对象,在线程被终止前,线程没有释放互斥对象。互斥对象的所属关系被授予调用线程,并且该互斥对象被置为非信号态。WAIT_OBJECT_0 :指定对象的状态被置为信号态。WAIT_TIMEOUT:超时,并且对象的状态为非信号态。如果函数调用失败,返回值是WAIT_FAILED 。若想获得更多错误信息,请调用GetLastError 函数。备注:WaitForSingleObjects 函数决定等待条件是否被满足。如果等待条件并没有被满足,调用线程进入个高效
23、的等待状态,当等待满足条件时占用非常少的处理器时间。在运行前。一个等待函数修改同步对象类型的状态。修改仅发生在引起函数返回的对象身上。例如,信号得计数减1。WaitForSingleObjects 函数能等待的对象包括:Change notification( 改变通告 ):Console input( 控制台输入 );Event(事件 );Job(作业 );Mutex( 互斥对象 );Process(进程 );Semaphore(信号量 );Thread(线程 );Waitable timer (可等待定时器 )。当使用等待函数或代码直接或间接创建窗口时,一定要小心。如果一个线程创建了任何窗
24、口,它必须处理进程消息。消息广播被发送到系统的所有窗口。一个线程用没有超时的等待函数也许会引起系统死锁。间接创建窗口的两个例子是DDE 和 COM CoInitialize 。因此,如果用户有一个创建窗口的线程,用MsgWaitForMultipleObjects或 MsgWaitForMultipleObjectEx函数,而不要用SignalObjectAndWait 函数。7.WaitForMultipleObjects 函数功能:WaitForMultipleObjects函数当下列条件之一满足时返回:(1)任意一个或全部指定对象处于信号态;(2)超时间隔已过。函数原型:DWORD Wa
25、itForMultipleObjects (DWORD nCount, CONST HANDLE *lpHandles, BOOL fWaitAll, DWORD dwMilliseconds)。参数: nCount:指定由 lpHandles 所指向的数组中的句柄对象数目最大对象句柄数目MAXIMUM_WAIT_OBJECTS 。 lpHandles:指向对象句柄数组的指针。该数组可以包含不同类型对象的句柄。在WindowsNT 中,该句柄必须有SYNCHRONIZE访问权限。若想获得更多的信息,请查看Standard Access Rights。 fWaitAll :指定等待类型。如果为T
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年操作系统学习课程设计方案 2022 操作系统 学习 课程设计 方案
限制150内