OS课程设计说明书.doc
《OS课程设计说明书.doc》由会员分享,可在线阅读,更多相关《OS课程设计说明书.doc(25页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、 操作系统课程设计报告书 Operation System Design Report名称:操作系统OS题目:多道程序缓冲区协调操作 班级:07级计算机应用1班课题负责人: 赖秋宏课题组成员:姓名 学号 班级 自评成绩 赖秋宏 8 07级计算机应用1班 A 郗艺超 5 07级计算机软件1班 B 赵主芳 8 07级计算机软件1班 B课题开发日期:2010.01.082010.01.141.概述在程序中使用多线程时,一般很少有多个线程能在其生命期内进行完全独立的操作。更多的情况是一些线程进行某些处理操作,而其它的线程必须对其处理结果进行了解。正常情况下对这种处理结果的了解应当在其处理任务完成后进行
2、。如果不采取适当的措施,其它线程往往会在线程处理任务结束前就去访问处理结果,这就很有可能得到有关处理结果的错误的了解。例如,多个线程同时访问同一个全局变量,如果都是读取操作,则不会出现问题。如果一个线程负责改变此变量的值,而其他线程负责同时读取变量内容,则不能保证读取到的数据是经过写线程修改后的。为了确保读线程读取到的是经过修改的变量,就必须在向变量写入数据时禁止其他线程对其的任何访问,直至赋值过程结束后再解除对其他线程的访问限制。像这种保证线程能了解其他线程任务处理结束后的处理结果而采取的保护措施即为线程同步。1.1目的通过本软件的演示,使学生更直观、更深入的明确操作系统进程、线程的概念。能
3、够知道为什么要使用多道程序的思想,以及怎么使用API创建多线程和使线程同步的基本方法。把课本上的P、V操作的思想运用到实践当中。掌握基本的VC编程,提高动手能力。1.2主要完成的任务对Buffer的操作的多线程同步问题,利用操作系统的P、V原语操作对put、move、get等多线程进行协调处理,实现了多道程序同时执行的原理PUT MOVE GET 图1 模型图对该模型(图1)实例化,利用图形界面直观易懂的特点,把完全抽象的线程的就绪、阻塞、执行的概念以及同步互斥的过程用图形动态的显示出来。1.3使用的开发工具VC+ 6.0, WINDOWS XP1.4解决的主要问题(1)线程的同步互斥。首先我
4、们要对问题进行正确的P、V操作的描述,然后选择适当的API加以描述。(2)图形显示模拟的问题。利用一定的图形清楚直观的反应抽象的数据,把整个模型的动态流程表示出来。(3)各功能模块的协调合作。要为各模块及程序做好运行时的状态保存,然后依据状态进行合适的操作。2.使用的基本概念和原理2.1程序、进程、线程程序:是指一个指令序列。进程:为执行程序指令的线程而保留的一系列资源的集合。线程:操作系统用来调度执行的最小单位。2.2线程的同步临界段临界段对象通过提供所有线程必须共享的对象来控制线程。只有拥有临界段对象的线程才可以访问保护资源(进行临界区操作)。在另一个线程可以获取对象的访问权。用户应用程序
5、可能会使用临界对象来阻止两个线程同时访问共享的资源发文件等。互斥量:互斥量的工作方式和临界段非常相似,其区别在于互斥量不公保护一个进程内的资源共享,而且还保护系统中进程之间的共享资源。它是通过为互斥量提供一个“互斥量名”来进行进程间资源共享协调的。事件事件对象用于给线程传递信号,指示线程中特定的操作可以开始或结束。除非线程已经收到了这个事件信号,否则它将一直处于挂起状态。当事件对象进入其信号状态时,正在等待该事件的线程就可以开始执行。例如,一个应用程序可以通过事件来通知线程它需要的数据已经准备好。经常利用事件进行线程之间的通信。信号量信号量与互斥相似,但是互斥只允许在同一时刻一个线程访问它的数
6、据,而信号量允许多个线程在同一时刻访问它的数据。WIN32 不知道哪一个线程拥有信号量,它只保证信号量使用的资源计数正确的设置。2.3 基本原理本程序使用信号量作为同步互斥的工具,当然也可以用其它的,通过对BUFFER1、BUFFER2、BUFFER3的容量,还有控制权设置不同的信号量来协调PUT、GET、MOVE线程,使其同步来实现P、V操作。本程序并非真正的传输数据,只是对一个数据计数器加减来模拟数据的增加减少,被送来被取走,然后通过定时刷新,将线程的状态、数据显示到界面上。3总体设计3.1基本的技术路线程序整体采用MFC编写,但是由于程序本身不是很复杂,所以没有使用严格的面向对象设计方法
7、。里面用到了很多未经封装的API和全局变量,可以说是在MFC的框架上用C语言写的。这样既利用了MFC的方便性,也保持了C语言的灵活性。3.2软件的总体结构、模块关系、总体流程模拟系统前台显示模块中间数模块后台线程模块图2 总体结构 显示模块数据层线程模块 设置 设置 显示 修改图3 模块关系参数设置开始暂停是否统计继续进行统计停止结束是否图4 流程图3.3 线程的规划我们创建三类线程:(1)PUT线程,分别向BUFFER1、BUFFER2里放数据,相当于生产者;(2)MOVE线程,从BUFFER1、BUFFER2里取数据并放到BUFFER3里,相当于搬运者;(3)GET线程,从BUFFER3里
8、取数据,相当于消费者。每类线程可由用户自行设定线程的个数。4.详细设计4.1要用到的API4.1.1创建线程的API:HANDLE WINAPI CreateThread( _in LPSECURITY_ATTRIBUTES lpThreadAttributes, _in SIZE_T dwStackSize, _in LPTHREAD_START_ROUTINE lpStartAddress, _in LPVOID lpParameter, _in DWORD dwCreationFlags, _out LPDWORD lpThreadId);lpThreadAttributes参数是一个指
9、向SECURITY_ATTRIBUTES结构的指针,表明了新创建的线程的安全属性。如果想使用线程内核对象的默认安全属性,可以向此参数传入NULL。dwStackSize参数表示为新建的线程分配多大的线程栈空间。lpStartAddress参数指定希望新线程执行的线程函数的地址。lpParameter参数用来向线程函数传递参数,通过这个参数,可以将一个初始值传递给线程函数。dwCreationFlags参数指定额外的标志来控制线程的创建。它可以是两个值之一。如果值为0,线程创建之后立即就可以进行调度。如果值为 CREATE_SUSPENDED,系统将创建并初始化线程,但是会暂停该线程的运行,这样
10、它就无法进行调度。lpThreadId参数用来存储系统分配给新线程的ID,如果我们以后需要用到线程的ID,那我们应写上这个参数,如果我们对线程的ID没兴趣,我们可以传递NULL。返回值:如果成功的话,返回的是新线程的句柄;如果失败,返回NULL。4.1.2挂起线程的API:DWORD WINAPI SuspendThread( _in HANDLE hThread);hThread参数指定的是要挂起的线程的句柄。这个句柄必须具有THREAD_SUSPEND_RESUME访问权限(可以在OpenThread中指定)。返回值:如果成功,返回值为当前线程被挂起的次数;如果失败,返回值为-14.1.3
11、唤醒线程的API:DWORD WINAPI ResumeThread( _in HANDLE hThread);hThread参数指定的是要唤醒的线程的句柄。这个句柄必须具有THREAD_SUSPEND_RESUME访问权限(可以在OpenThread中指定)。返回值:如果成功,返回值为当前线程被挂起的次数;如果失败,返回值为-14.1.4结束线程函数:BOOL WINAPI TerminateThread( _in_out HANDLE hThread, _in DWORD dwExitCode);hThread参数指定的是要结束的线程的句柄。这个句柄必须具有THREAD_TERMINATE
12、访问权限(可以在OpenThread中指定)。dwExitCode参数是线程函数的返回值。返回值:如果成功,返回值为非零;如果失败,返回值为零。4.1.5打开线程的API:HANDLE WINAPI OpenThread( _in DWORD dwDesiredAccess, _in BOOL bInheritHandle, _in DWORD dwThreadId);dwDesiredAccess参数指定线程对象的访问权限。bInheritHandle参数指定此线程是否可被子进程继承。dwThreadId参数为要打开的线程的ID。返回值:如果成功,返回值为指定打开的线程的句柄;如果失败,返回
13、值为NULL。4.1.6等待函数:DWORD WINAPI WaitForSingleObject( _in HANDLE hHandle, _in DWORD dwMilliseconds);hHandle参数为要等待的对象的句柄。等待的对象可以为:进程、线程、作业、文件以及控制台的标准输入/输出/错误流、事件、可等待的计时器、信号量、互斥量。这些对象都可以处于触发状态和非触发状态。dwMilliseconds参数指定线程等待的最长时间。当我们传入INFINITE,线程就会一直等待,直到等待的对象变为触发状态。返回值:成功的话,返回值为表示函数返回原因的一个DWORD值;如果失败,返回WAI
14、T_FAILED。4.1.7进入临界区函数:void WINAPI EnterCriticalSection( _in_out LPCRITICAL_SECTION lpCriticalSection);lpCriticalSection参数是指向一个临界区对象的指针。返回值:这个函数没有返回值。4.1.8离开临界区函数:void WINAPI LeaveCriticalSection( _in_out LPCRITICAL_SECTION lpCriticalSection);lpCriticalSection参数是指向一个临界区对象的指针。返回值:没有返回值4.2主要的类、函数程序中主要的
15、类:我们为每个对话框设计一个类,它们各自的消息都在自己的消息处理函数中处理。另外还有一个程序类,为MFC自动生成。程序中主要的函数:生产者线程函数、搬运者线程函数、消费者线程函数以及各个对话框中控件的消息响应函数。生产者线程函数:UINT ThreadProFanc(LPVOID lparam);参数我们为它传递主对话框的指针,一边在线程函数中可以对主对话框进行操作。搬运者线程函数:UINT ThreadMoverFanc(LPVOID lparam);参数同上。消费者线程函数:UINT ThreadCustomerFanc(LPVOID lparam);参数同上。5.编码设计5.1开发环境的
16、设置和建立打开VS2008,点击文件新建项目,弹出新建项目对话框,选择MFCMFC应用程序,为我们的项目起一个名字,点击确定,打开MFC应用程序向导。我们选择基于对话框的MFC应用程序,单击完成,项目创建完成。过程如下各图。 图1 新建项目对话框图2 MFC应用程序向导5.2程序界面程序主界面:图3 程序主界面参数设置界面: 图4 参数设置界面数据汇总结果界面:图5 汇总结果界面5.3程序中要用到的信号量和临界区根据题目的要求,很容易确定需要四个信号量,两个临界区。四个信号量分别为:HANDLE SE1;/判断Buffer1是否有数据HANDLE SD1;/判断Buffer1是否有空间HAND
17、LE SE11;/判断Buffer2是否有数据HANDLE SD11;/判断Buffer2是否有空间HANDLE SE2;/判断Buffer3是否有数据HANDLE SD2;/判断Buffer3是否有空间两个临界区为:CRITICAL_SECTION g_cs1; /用于对buffer1的互斥操作CRITICAL_SECTION g_cs11; /用于对buffer2的互斥操作CRITICAL_SECTION g_cs2; /用于对buffer3的互斥操作5.4主要的程序代码void CBufferDlg:OnBnClickedButton1()/开始按钮/ TODO: 在此添加控件通知处理程
18、序代码int i;int j;int k; /将参数至零,让线程在调用函数中继续循环m_proExit=0;m_moverExit=0;m_customerExit=0; /禁用开始按钮GetDlgItem(IDC_BUTTON1)-EnableWindow(FALSE);/激活暂停按钮 GetDlgItem(IDC_BUTTON2)-EnableWindow(TRUE);/激活停止按钮 GetDlgItem(IDC_BUTTON8)-EnableWindow(TRUE); GetDlgItem(IDC_BTN_CONFIG)-EnableWindow(FALSE);GetDlgItem(ID
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OS 课程设计 说明书
限制150内