您好,欢迎访问三七文档
当前位置:首页 > 行业资料 > 其它行业文档 > 操作系统实验四--同步机构
实验四同步机构一、实验内容模拟实现用同步机构避免并发进程执行时可能出现的与时间有关的错误。二、实验目的进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。我们把如干个进程都能进行访问和修改地那些变量成为公共变量。由于进程是并发执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后,所得到的结果与访问公共变量的时间有关。为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。一般说,同步机构是由若干条原语——同步原语——所组成。本实验要求学生模拟PV操作同步机构的实现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。三、实验题目模拟PV操作同步机构,且用PV操作解决生产者——消费者问题。四、实验步骤(1)程序中使用的数据结构及符号说明structspcb{charname;//进程名字charstate;//进程状态charwhy;//等待原因intdd;//断点};typedefstructspcbpcb;pcbproducter,consumer,*process,*process1;//各个进程控制块ints1,s2,i,j,in,out,pc,m;chararray[10];charc,x;intpa[6],sa[6];(2)流程图初始化程序:模拟实验的程序从初始化程序入口启动,初始化工作包括对信号量S1、S2赋初值,对生产者、消费者进程的PCB初始化。初始化后转向处理器调度程序,其流程如图1:图1:初始化流程处理器调度程序:在计算机系统中,进程并发执行时,任一进程占用处理器执行完一条指令后就有可能被打断而让出处理器由其他进程运行。故在模拟系统中也类似处理,每当执行一条模拟的指令后,保护当前进程的现场,让它成为非运行状态,由处理器调度程序按随机数再选择一个就绪进程占用处理器运行。处理器调度程序流程见图2:开始初始化信号量S1,S2S1:=10,S2:=0处理器调度程序生产者和消费者进程的PCB中状态为就绪,断点为0将现行进程置为生产者进程,PC:=0结束图2:处理器调度程序流程模拟处理器指令执行程序:按“指令计数器”PC之值执行指定的质量,且PC加1指向下一条指令。模拟处理器指令执行的程序流程见图3和图4:开始随即选择—就绪进程作为现行进程模拟处理器指令执行程序将现行进程状态改为运行态现行进程PCB的断点值=PC结束保护现场,PC=当前进程PCB的断点有就绪进程?否是图3:模拟处理器指令执行P(s)GOTO空操作PutGETproduceconsumeV(s)开始j:=PC按j转向各模拟指令对应的过程现行进程为生产者?否是j:=SA[i]j:=PA[i]PC:=i+1置现行进程为就绪态返回生产者运行结束?置生产者进程为完成态是否(1)模拟P(S)(2)模拟V(S)图4:模拟PV操作的执行另外,为了使得模拟程序有一个结束条件,在图3中附加了“生产者运行结束”的条件判断,模拟时可以采取人工选择的方法实现。图4给出了P(S)和V(S)模拟指令执行过程的流程。(3)源代码#includestdio.h#includestdlib.h#includeconio.h#includewindows.h#defineNULL0structspcb{charname;//进程名字charstate;//进程状态charwhy;//等待原因intdd;//断点};typedefstructspcbpcb;pcbproducter,consumer,*process,*process1;ints1,s2,i,j,in,out,pc,m;chararray[10];开始S←S-1将调用P(s)过程的进程置为就绪将调用P(s)过程的进程置为等待信号量s的状态S0返回否是开始S←S+1将调用V(s)过程的进程置为就绪找一个等待s信号量的进程置为就绪态S0返回否是charc,x;intpa[6],sa[6];intp(ints)/*p操作原语*/{s=s-1;if(s0){process-state='B';/*B表示阻塞*/process-why='s';}else{process-state='W';/*W表示就绪*/}return(s);}intv(ints)/*v操作原语*/{s=s+1;if(s=0){process1-state='W';}process-state='W';return(s);}charRanChar(){chararr[10]={'a','b','c','d','e','f','g','h','i','j'};returnarr[abs(rand()%10)];}voidput(){Sleep(1000);array[in]=RanChar();in=(in+1)%10;printf(productacharis%c!\n,array[in-1]);intk=0;for(m=0;m10;m++){if(array[m]!=''){printf(%c,array[m]);k=k+1;}}printf(缓冲池中有%d个产品\n,k);}voidget(){Sleep(1000);x=array[out];printf(\n%cgetacharfronbuffer,x);printf(\n);array[out]='';out=(out+1)%10;intk=0;for(m=0;m10;m++){if(array[m]!=''){printf(%c,array[m]);k=k+1;}}printf(缓冲池中有%d个产品\n,k);}voidgotol(){pc=0;}voidnop(){;}voiddisp()/*建立进程显示函数,用于显示当前进程*/{printf(\nname\tstate\twhy\tdd\n);printf(|%c\t,process-name);printf(|%c\t,process-state);printf(|%c\t,process-why);printf(|%d\t,process-dd);printf(\n);}voidinit()/*初始化程序*/{s1=10;/*s1表示空缓冲区的数量*/s2=0;/*s2表示满缓冲区的数量*/producter.name='p';/*对生产者进程初始化*/producter.state='W';producter.why='';producter.dd=0;consumer.name='c';/*对消费者进程初始化*/consumer.state='W';consumer.why='';consumer.dd=0;for(intk=0;k10;k++){array[k]='';}}voidbornpa()/*将生产者程序装入pa[]中*/{for(i=0;i=3;i++){pa[i]=i;}}voidbornsa()/*将消费者程序装入sa[]中*/{for(i=0;i=3;i++){sa[i]=i;}}voiddiaodu()/*处理器调度程序*/{while((producter.state=='W')||(consumer.state=='W')){x=rand();/*x随机获得一个数*/x=x%2;/*对X取于*/if(x==0)/*若X等于零,则执行生产者进程,反之执行消费者进程*/{process=&producter;/*process表示现行进程,将现行进程置为生产者进程*/process1=&consumer;}else{process=&consumer;process1=&producter;}pc=process-dd;i=pc;/*此时把PC的值付给I*/if((process-name=='p')&&(process-state=='W')){j=pa[i];pc=i+1;switch(j){case0:s1=p(s1);process-dd=pc;break;case1:put();process-state='W';process-dd=pc;break;case2:s2=v(s2);process-dd=pc;break;case3:gotol();process-state='W';process-dd=pc;}}elseif((process-name=='c')&&(process-state=='W'))/*执行消费者进程且该进程处于就绪状态*/{process-state='W';j=sa[i];pc=i+1;switch(j){case0:s2=p(s2);process-dd=pc;break;/*申请资源,若没有申请到则跳转*/case1:get();process-dd=pc;break;case2:s1=v(s1);process-dd=pc;break;case3:gotol();process-state='W';process-dd=pc;}}/*endelse*/}/*endwhile*/printf(\nTheprogramisover!\n);}voidmain(){init();bornpa();bornsa();diaodu();}五、实验总结信号量(semaphore)和P、V操作的同步机构可以有效地解决临界区的问题,使用信号控制相互合作的进程。当进程检测到信号后,就被迫停止在摸个地方,直到收到专门的信号才能继续执行。在这个实验里面,要考虑两种错误的情况:1、生产者不可以向已经满了的缓冲区里面添加产品;2、消费者不能从空了的缓冲区里面取产品。通过这个实验,可以帮助我们很好的理解进程同步的问题,要解决进程同步需要做哪些工作,如何利用信号量机制来解决进程同步问题等等,这些问题其实我们在学习理论知识时都是很少思考的,因为感触不深,所以学了一遍就过去了,但是在自己做实验时才会发现哪些地方是我们需要考虑的,哪些地方是需要注意的,实验给了我们实践的机会,给了我们理论结合实际的机会,从实验中可以学到很多东西,不仅仅是书本上的东西这么简单,更重要的是对待事情严谨的态度。
本文标题:操作系统实验四--同步机构
链接地址:https://www.777doc.com/doc-4603281 .html