多道程序缓冲区协调操作操作系统设计.doc_第1页
多道程序缓冲区协调操作操作系统设计.doc_第2页
多道程序缓冲区协调操作操作系统设计.doc_第3页
多道程序缓冲区协调操作操作系统设计.doc_第4页
多道程序缓冲区协调操作操作系统设计.doc_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

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

文档简介

操作系统课程设计报告题 目:多道程序缓冲区协调操作班 级:课题负责人: 课题组成员:编译环境:vc+6.0日 期:2014年1月10日多道程序缓冲区协调操作1.概述在程序中使用多线程时,一般很少有多个线程能在其生命期内进行完全独立的操作。更多的情况是一些线程进行某些处理操作,而其它的线程必须对其处理结果进行了解。正常情况下对这种处理结果的了解应当在其处理任务完成后进行。如果不采取适当的措施,其它线程往往会在线程处理任务结束前就去访问处理结果,这就很有可能得到有关处理结果的错误的了解。例如,多个线程同时访问同一个全局变量,如果都是读取操作,则不会出现问题。如果一个线程负责改变此变量的值,而其他线程负责同时读取变量内容,则不能保证读取到的数据是经过写线程修改后的。为了确保读线程读取到的是经过修改的变量,就必须在向变量写入数据时禁止其他线程对其的任何访问,直至赋值过程结束后再解除对其他线程的访问限制。像这种保证线程能了解其他线程任务处理结束后的处理结果而采取的保护措施即为线程同步。1.1设计目的(1)了解提出信号量的背景 (2)掌握信号量的基本概念及 pv 操作的原理 (3)进一步熟悉信号量解决的经典问题 (4)利用信号量的原理实现不同操作系统下同步互斥问题1.2设计要求(1) 可以随机产生字符数据,由put操作放入buff1,buffer中容量单位是字符。 (2) 提供良好图形界面,显示buffer的操作过程。(3) 可以设定各buffer的容量、put、get、move操作的个数;(4) 可以设定put、get、move操作的速度;(5) 实时显示每个buffer中数据的个数和数据的内容,空闲buffer的空间的个数;(6) 实时显示线程、进程所处于等待(阻塞)状态的个数(7)程序运行结束,显示汇总数据:总的运行时间;buffer中数据的个数;已放入buffer的数据个数;已取出的数据个数;平均每个buffer中的数据个数。1.3主要完成的任务putmove2buffer1buffer2buffer3get2move1get3图1对该模型(图1)实例化,利用图形界面直观易懂的特点,把完全抽象的线程的就绪、阻止、运行的概念以及同步互斥的过程用图形动态的显示出来。1.4环境、工具 vc+ 6.0,window72使用的基本概念和原理2.1基本概念信号量:为解决多进程线程同步与互斥问题,让两个或多个多道进程线程通过特殊的变量展开交互。线程:是进程的一个实体,是进程上下文中执行的代码序列,是被系统调度的基本单元。进程:进程是正在运行的程序实体,并且包括这个运行的程序中占据的所有系统资源。互斥与同步:进程的同步与互斥是指进程在推进时的相互制约关系。进程同步:它主要源于进程合作,是进程间共同完成一项任务时直接发生相互作用的关系。进程互斥:它主要源于资源共享,是进程之间的间接制约关系。2.2 基本原理本程序使用信号量作为同步互斥的工具,当然也可以用其它的,通过对buffer1、buffer2、buffer3的容量,还有控制权设置不同的信号量来协调put、get2、get3、move1、move2线程,使其同步来实现p、v操作。本程序并非真正的传输数据,只是对一个数据计数器加减来模拟数据的增加减少,被送来被取走,然后通过定时刷新,将线程的状态、数据显示到界面上。3总体设计3.1基本的技术路线mfc中已实现有对线程操作和同步互斥的全部类,但是他对实现p、v操作的模拟不够直观;使用api面向过程的话,比较灵活,但程序的可读性、维护性较差。我们使用二者的优点,取长补短,采用混合编程的方式对问题进行描述和演示。3.2软件的总体结构、模块关系、总体流程模拟系统前台显示模块中间数模块后台线程模块图1 总体结构 显示模块数据层线程模块 设置 设置 显示 修改图2 模块关系参数设置开始暂停是否统计继续进行统计停止结束是否图3 流程图33线程规划我们创建三类线程:(1)put线程(往buffer1里放数据,相当于生产者)。(2)move1线程(从buffer1里取数据并放到buffer2里,相当于搬运者)。 move2线程(从buffer1里取数据并放到buffer3里,相当于搬运者)。(3)get2线程(从buffer2里取数据,相当于消费者)。get3线程(从buffer3里取数据,相当于消费者)。每类线程可由用户自行设定线程的个数。4详细设计 4.1设计思想设计了3个主要函数,分别为:生产者函数put,消费者函数get2 、get3,转移函数move1 、move2,下面详细介绍各个类的功能。put函数用于实现通过执行p操作判断buffer1是否有空,buffer1是否可操作,并向buffer1中置数据,同时将表示buffer1中数据数buffer1number加+1,放入数据后执行v操作。move1函数通过执行p操作来判断buffer1中是否有数据,是否可操作,buffer2中是否有空间,是否可操作,将buffer1中的数据移至buffer2中,并使buffer1number-,buffer2number+,确定buffer中现有的数据总数。之后再进行相应的v操作。move2函数通过执行p操作来判断buffer1中是否有数据,是否可操作,buffer3中是否有空间,是否可操作,将buffer1中的数据移至buffer3中,并使buffer1number-,buffer3number+,确定buffer中现有的数据总数。之后再进行相应的v操作。get2函数用于实现通过执行p操作判断buffer2是否有数据,buffer2是否可操作,并从buffer2中取数据,同时将表示buffer2中数据数buffer2number-,放入数据后执行v操作。get3函数用于实现通过执行p操作判断buffer3是否有数据,buffer3是否可操作,并从buffer3中取数据,同时将表示buffer3中数据数buffer3number-,放入数据后执行v操作。4.2设计原理生产者消费者问题是相互合作的进程关系的一种抽象,可以利用信号量机制来解决生产者消费者问题,利用互斥信号量mutex实现进程对缓冲池的互斥使用。对信号量的操作只能通过两个原子操作:wait(s)和signal(s).wait(s)是等待信号的操作,进行s=s-1操作;signal(s)是发送信号的操作,进行s=s+1操作。wait 若s-1后仍大于或等于零,则进程继续执行;若s-1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转进程调度;若相加结果大于或等于零,则从该信号的等待队列中唤醒一等待进程,然后再返回原进程继续执行或转进程调度4.3信号量的设置需要设置九个信号量full1 empty1 buffer1 full2 empty2 buffer2 full3 empty3 buffer3。各信号量含义及初值如下:full1表示buffer1是否有数据,初值为0;empty1表示buffer1是否有空间,初值为m;buffer1表示buffer1是否可操作,初值为1;full2表示buffer2是否有数据,初值为0;empty2表示buffer2是否有空间,初值为n;buffer2表示buffer2是否可操作,初值为1。full3表示buffer2是否有数据,初值为0;empty3表示buffer2是否有空间,初值为p;buffer3表示buffer2是否可操作,初值为1。4.4基本函数说明(1)线程创建函数handle createthread(lpsecurity_attributes lpthreadattributes./线程安全属性dword dwstacksize,/线程堆栈的初始化大小,等于0时为系统默认的堆栈大小plthread_start_routine lpstartaddress,/线程函数lpvoid lpparameter,/线程参数dword dwcreationflags,/创建方式lpdword lpthreadid/线程标识符该函数创建一个线程,如果没有特殊需要除第三个参数外都可设为0,按系统的默认取值对待,主要是第三个参数,它是线程程序的入口,线程序入口的标准形式为uint function(lpvoid param)线程函数里可以传一个指针做为参数(param),该参数由创建线程函数(createthread)里的第四个参数确定。(2)信号量创建函数handle createsemaphore(lpsecurity_attributes lpsemaphoreattributes, / 安全属性指针long linitialcount, / 初始计数long lmaximumcount, / 最大计数lpctstr lpname / 对象名指针)该函数创建一个信号量,llnitialcount 是对信号量的初始值,imaximuncount为信号量的最大值,即信号量在一个范围内有效,例empty=:createsemaphore(0,0,m,0);第二个0为empty信号量的初始值,m为信号量的最大值,在这个范围内(0,m)信号量都是有信号的。(3) 信号量释放函数bool releasesemaphore(handle hsemaphore, / 信号量句柄long lreleasecount, / 计数递增数量lplong lppreviouscount / 先前计数)该函数为释放信号量,因为信号量为系统资源,数目有限,所以使用完毕后,最后将资源释放。(4)等待函数dword waitforsingleobjec(handle hhandle,/对象句柄dword dwmilliseconds/等待的时间,单位为毫秒)5.编码设计5.1开发环境的设置和建立打开vc+,点击文件新建项目,弹出新建项目对话框,选择mfcmfc应用程序,为我们的项目起一个名字,点击确定。我们选择基于对话框的mfc应用程序,单击完成,项目创建完成。如下图。5.2程序界面5.3主要的程序代码/ homeworkdlg.cpp : implementation file/#include stdafx.h#include homework.h#include homeworkdlg.h#ifdef _debug#define new debug_new#undef this_filestatic char this_file = _file_;#endif/#define delay 1000#define p(s) :waitforsingleobject(s,infinite)#define v(s) :releasesemaphore(s,1,null)/ caboutdlg dialog used for app aboutvoid drawarrow(crect rc,cdc *pdc,colorref col);void drawbuffer(int x,int number,cdc * pdc);class caboutdlg : public cdialogpublic:caboutdlg();/ dialog data/afx_data(caboutdlg)enum idd = idd_aboutbox ;/afx_data/ classwizard generated virtual function overrides/afx_virtual(caboutdlg)protected:virtual void dodataexchange(cdataexchange* pdx); / ddx/ddv support/afx_virtual/ implementationprotected:/afx_msg(caboutdlg)/afx_msgdeclare_message_map();caboutdlg:caboutdlg() : cdialog(caboutdlg:idd)/afx_data_init(caboutdlg)/afx_data_initvoid caboutdlg:dodataexchange(cdataexchange* pdx)cdialog:dodataexchange(pdx);/afx_data_map(caboutdlg)/afx_data_mapbegin_message_map(caboutdlg, cdialog)/afx_msg_map(caboutdlg)/ no message handlers/afx_msg_mapend_message_map()/ chomeworkdlg dialogchomeworkdlg:chomeworkdlg(cwnd* pparent /*=null*/): cdialog(chomeworkdlg:idd, pparent)/afx_data_init(chomeworkdlg)m_put = 0;delay = 0;m = 0;n = 0;m_move1 = 0;m_get2 = 0;m_get3 = 0;m_move2 = 0;p = 0;/afx_data_init/ note that loadicon does not require a subsequent destroyicon in win32m_hicon = afxgetapp()-loadicon(idr_mainframe);void chomeworkdlg:dodataexchange(cdataexchange* pdx)cdialog:dodataexchange(pdx);/afx_data_map(chomeworkdlg)ddx_control(pdx, idc_spin9, m_sbbuffer3);ddx_control(pdx, idc_spin8, m_sbmove2);ddx_control(pdx, idc_spin7, m_sbget3);ddx_control(pdx, idc_spin3, m_sbget2);ddx_control(pdx, idc_spin2, m_sbmove1);ddx_control(pdx, idc_spin6, m_sbbuffer2);ddx_control(pdx, idc_spin5, m_sbbuffer1);ddx_control(pdx, idc_spin4, m_delay);ddx_control(pdx, idc_spin1, m_sbput);ddx_text(pdx, idc_edit1, m_put);ddv_minmaxint(pdx, m_put, 1, 15);ddx_text(pdx, idc_edit4, delay);ddv_minmaxint(pdx, delay, 300, 1000);ddx_text(pdx, idc_edit5, m);ddv_minmaxint(pdx, m, 1, 20);ddx_text(pdx, idc_edit6, n);ddv_minmaxint(pdx, n, 1, 20);ddx_text(pdx, idc_edit2, m_move1);ddv_minmaxint(pdx, m_move1, 1, 15);ddx_text(pdx, idc_edit3, m_get2);ddv_minmaxint(pdx, m_get2, 1, 10);ddx_text(pdx, idc_edit7, m_get3);ddv_minmaxint(pdx, m_get3, 1, 10);ddx_text(pdx, idc_edit8, m_move2);ddv_minmaxint(pdx, m_move2, 1, 15);ddx_text(pdx, idc_edit9, p);ddv_minmaxint(pdx, p, 1, 20);/afx_data_mapbegin_message_map(chomeworkdlg, cdialog)/afx_msg_map(chomeworkdlg)on_wm_syscommand()on_wm_paint()on_wm_querydragicon()on_bn_clicked(idc_button1, onbutton1)on_bn_clicked(idc_button2, onbutton2)on_wm_timer()on_bn_clicked(idc_button3, onbutton3)/afx_msg_mapend_message_map()/ chomeworkdlg message handlersbool chomeworkdlg:oninitdialog()cdialog:oninitdialog();/ add about. menu item to system menu./ idm_aboutbox must be in the system command range.assert(idm_aboutbox & 0xfff0) = idm_aboutbox);assert(idm_aboutbox appendmenu(mf_separator);psysmenu-appendmenu(mf_string, idm_aboutbox, straboutmenu);/ set the icon for this dialog. the framework does this automatically/ when the applications main window is not a dialogseticon(m_hicon, true);/ set big iconseticon(m_hicon, false);/ set small iconbuffer1number = buffer2number =buffer3number= putid =get2id=get3id =move1id=move2id = 0;alltime=allnumber1=allnumber2=allnumber3 =0;bput =bget2=bget3=bkill=bmove1=bmove2=false;cwnd * pwnd = this-getdlgitem(idc_static);pwnd-getwindowrect(&rcupdate);this-screentoclient(&rcupdate);m_put = m_get2=m_get3=m_move1=m_move2 =1;m=n=p=5;delay =500;this-updatedata(false);m_sbget2.setrange(1,15);m_sbget3.setrange(1,15);m_sbmove1.setrange(1,15);m_sbmove2.setrange(1,15);m_sbput.setrange(1,15);m_delay.setrange(300,1000);m_sbbuffer1.setrange(1,20);m_sbbuffer2.setrange(1,20);m_sbbuffer3.setrange(1,20);return true; / return true unless you set the focus to a controlvoid chomeworkdlg:onsyscommand(uint nid, lparam lparam)if (nid & 0xfff0) = idm_aboutbox)caboutdlg dlgabout;dlgabout.domodal();elsecdialog:onsyscommand(nid, lparam);/ if you add a minimize button to your dialog, you will need the code below/ to draw the icon. for mfc applications using the document/view model,/ this is automatically done for you by the framework.void chomeworkdlg:onpaint() if (isiconic()cpaintdc dc(this); / device context for paintingsendmessage(wm_iconerasebkgnd, (wparam) dc.getsafehdc(), 0);/ center icon in client rectangleint cxicon = getsystemmetrics(sm_cxicon);int cyicon = getsystemmetrics(sm_cyicon);crect rect;getclientrect(&rect);int x = (rect.width() - cxicon + 1) / 2;int y = (rect.height() - cyicon + 1) / 2;/ draw the icondc.drawicon(x, y, m_hicon);elsecpaintdc dc(this);colorref col;for(int i=1;i=m_put;i+)crect rc(20,i*10+20,120,(i+1)*10+20);if(putid =i&bput)col=rgb(255,0,255);elsecol=rgb(0,0,205,);drawarrow(rc,&dc,col);for(int j=1;j=m_get2;j+)crect rc1(600,j*10+20,700,(j+1)*10+20);if(get2id =j&bget2)col=rgb(255,0,255);elsecol=rgb(0,0,205);drawarrow(rc1,&dc,col);for(int n=1;n=m_get3;n+)crect rc2(1100,n*10+20,1200,(n+1)*10+20);if(get3id =n&bget3)col=rgb(255,0,255);elsecol=rgb(0,0,205);drawarrow(rc2,&dc,col);for(int m=1;m=m_move1;m+)crect rc3(300,m*10+20,400,(m+1)*10+20);if(move1id=m&bmove1)col=rgb(255,0,255);elsecol=rgb(0,0,205);drawarrow(rc3,&dc,col);for(int p=1;pselectobject(&br);pdc-beginpath();pdc-moveto(rc.left,rc.top+rc.height()/4);pdc-lineto(rc.right-rc.width()/4,rc.top+rc.height()/4);pdc-lineto(rc.right-rc.width()/4,rc.top);pdc-lineto(rc.right,rc.top+rc.height()/2);pdc-lineto(rc.right-rc.width()/4,rc.bottom);pdc-lineto(rc.right-rc.width()/4,rc.bottom-rc.height()/4);pdc-lineto(rc.left,rc.bottom-rc.height()/4);pdc-lineto(rc.left,rc.top+rc.height()/4);pdc-endpath();pdc-fillpath();pdc-selectobject(oldbrush);uint put(lpvoid lparam)chomeworkdlg * dlg =(chomeworkdlg *) lparam;int i =dlg-current;while(!dlg-bkill)p(dlg-full1);p(dlg-buffer1);dlg-putid=i;dlg-buffer1number+=1;dlg-bput=true;dlg-allnumber1+;:sleep(dlg-delay);v(dlg-buffer1);v(dlg-empty1);dlg-bput=false;return 0;uint move1(lpvoid lparam)chomeworkdlg *dlg = (chomeworkdlg *)lparam;int i =dlg-current;while(!dlg-bkill)p(dlg-empty1);p(dlg-full2);p(dlg-buffer1);p(dlg-buffer2);dlg-bmove1=true;dlg-buffer1number-;dlg-buffer2number+;dlg-move1id=i;:sleep(dlg-delay);v(dlg-buffer1);v(dlg-buffer2);v(dlg-empty2);v(dlg-full1);dlg-bmove1=false;return 0;uint move2(lpvoid lparam)chomeworkdlg *dlg = (chomeworkdlg *)lparam;int i =dlg-current;while(!dlg-bkill)p(dlg-empty1);p(dlg-full3);p(dlg-buffer1);p(dlg-buffer3);dlg-bmove2=true;dlg-buffer1number-;dlg-buffer3number+;dlg-move2id=i;:sleep(dlg-delay);v(dlg-buffer1);v(dlg-buffer3);v(dlg-empty3);v(dlg-full1);dlg-bmove2=false;return 0;uint get2(lpvoid lparam)chomeworkdlg * dlg = (chomeworkdlg *)lparam;int i =dlg-current;while (!dlg-bkill)p(dlg-empty2);p(dlg-buffer2);dlg-get2id=i;dlg-buffer2number-;dlg-bget2=true;dlg-allnumber2+;:sleep(dlg-delay);v(dlg-buffer2);v(dlg-full2);dlg-bget2=false;return 0;uint get3(lpvoid lparam)chomeworkdlg * dlg = (chomeworkdlg *)lparam;int i =dlg-current;while (!dlg-bkill)p(dlg-empty3);p(dlg-buffer3);dlg-get3id=i;dlg-buffer3number-;dlg-bget3=true;dlg-allnumber3+;:sleep(dlg-delay);v(dlg-buffer3);v(dlg-full3);dlg-bget3=false;return 0;void chomeworkdlg:onbutton1() if(bmove1|bmove2|bget2|bget3|bput)messagebox(threads is runing);return;if(binstall)this-onbutton3();allnumber1=allnumber2=allnumber3=alltime =0;this-settimer(3,100,0);bkill=false;cwinthread * pthread;for(int m=1;mcurrent=m;pthread = afxbeginthread(move1,this);hdm-1 =pthread-m_hthread;for(int p=1;pcurrent=p;pthread = afxbeginthread(move2,this);hdm_move1+p =pthread-m_hthread;for(int i=1;icurrent=i;pthread = afxbeginthread(put,this);hdm_move1+m_move2+i =pthread-m_hthread;for(int j=1;jcurrent=j;pthread = afxbeginthread(get2,this);hdm_move1+m_move2+m_put+j = pthread-m_hthread;for(int n=1;ncurrent=n;pthread = afxbeginthread(get3,this);hdm_move1+m_move2+m_put+m_get2+n = pthread-m_hthread;void chomeworkdlg:onbutton2() bkill=true;:waitformultipleobjects(m_move1+m_move2+m_put+m_get2+m_get3,hd,true,null);this-killtimer(3);char str1000;sprintf(str,use %ldmsn put %ld datan get2 %ld datan get3 %ld datan buffer1 %ld datan buffer2 %ld datan buffer3 %ld datan,alltime*300,allnumber1,allnumber2,allnumber3,buffer1number,buffer2number,buffer3number);messagebox(str);void chomeworkdlg:ontimer(uint nidevent) alltime+;this-invalidaterect(&rcupdate);cdialog:ontimer(nidevent);void chomeworkdlg:onbutton3() if(bmove1|bm

温馨提示

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

评论

0/150

提交评论