1、实验四同步机构实验四-同步机构实验四 同步机构 一. 实验内容 模拟实现用同步机构避免并发进程执行时可能出现的与时间有关的错误。 二. 实验目的 进程是程序在一个数据集合上运行的过程,进程是并发执行的,也即系统中的多个进程轮流地占用处理器运行。 我们把若干个进程都能进行访问和修改的那些变量称为公共变量。由于进程是并发执行的,所以,如果对进程访问公共变量不加限制,那么就会产生“与时间有关”的错误,即进程执行后,所得到的结果与访问公共变量的时间有关。为了防止这类错误,系统必须要用同步机构来控制进程对公共变量的访问。一般说,同步机构是由若干条原语同步原语所组成。本实验要求学生模拟PV操作同步机构的实
2、现,模拟进程的并发执行,了解进程并发执行时同步机构的作用。 三. 实验题目 模拟PV操作同步机构,且用PV操作解决生产者消费者的问题。 四. 实验步骤 (1) 程序中使用的数据结构及符号说明 struct PCB /进程控制块 char p_name23; int m;/ 0:运行,1:就绪,2:等待,3:完成; int waitreason;/0:信号S1,1:信号S2; int interuptpoint; /设置断点 ; const int num=5; const int sales=10; struct PCB; /进程控制块 void ce(); void p(int & s,in
3、t p,PCB *d); /P操作 void v(int & s,int p,PCB *d); /V操作 (2) 流程图 程序总体结构框图: 开始 初始化 运行 结束 初始化: 初始化信号量S1,S2(S1=10,S2=0),对生产者、消费者进程的PCB初始化。 初始化流程图: 运行部分框图: 开始 初始化指针 打印进程信息 进程队列为Y 空, N 选择当前进程 结束 运行时间加1 Y 当前进程运行完毕, 打印进程信息 N 打印进程信息 删除当前进程 调整指针 调整指针 (3) 源代码(附注释) /#include stdafx.h #include #include #include usi
4、ng namespace std; const int num=5; const int sales=10; struct PCB; /进程控制块 void ce(); void p(int & s,int p,PCB *d); /P操作 void v(int & s,int p,PCB *d); /V操作 /*int _tmain(int argc, _TCHAR* argv) return 0; */ struct PCB /进程控制块 char p_name23; int m;/ 0:运行,1:就绪,2:等待,3:完成; int waitreason;/0:信号S1,1:信号S2; in
5、t interuptpoint; /设置断点 ; int produce(int &C,int c) /生产产品c C=c; return C; int s1,s2,panum,sanum,pc; PCB producer,customer,*currp; void initial() /初始化程序 strcpy_s(producer.p_name,producer); producer.m=1; /初始化生产者为就绪状态 producer.interuptpoint=0; strcpy_s(customer.p_name,customer); customer.m=1; /初始化消费者为就绪
6、状态 customer.interuptpoint=0; currp=&producer; s1=10; s2=0; for(int i=0;iinteruptpoint=pc; /令当前执行指令送到断点中 int n; while(producer.m=1|customer.m=1)/判断当前执行是生产者,还是消费者 coutn; if(n=0)/0为表示生产者 if(producer.m=1) currp=&producer; else/否则消费者为就绪状态,执行消费者进程 cout进程producer被挂起,无法执行,执行进程customerendl; currp=&customer;
7、else if(n=1)/1为表示消费者 if(customer.m=1) currp=&customer; else/否则生产者为就绪状态,执行消费者进程 cout进程customer被挂起,无法执行,执行进程producerm=0; /令当前进程处于执行状态 pc=currp-interuptpoint; ce();/执行 currp-interuptpoint=pc; void ce() int i,j,q,pt,xx,ss,nq,shangpinsales,xiaofeisales; int C; char w; xx=0; ss=0; nq=0 i=pc if(strcmp(curr
8、p-p_name,producer)=0)/pai存放生产者程序中的一条模拟指令执行的入口地址 j=pai; q=0; else /sai存放消费者程序中的一条模拟指令执行的入口地址 j=sai; q=1; pc=i+1; switch(j)/j表示当前程序中的一条模拟指令执行的入口地址 case 0: if(q=0)/输入一个字符放入中 coutpt; produce(C,pt); /pp=pt; currp-m=1; cout产品已经生产; else /执行消费者的P操作 nq=2; p(s2,nq,currp); break; case 1: if(q=0)/执行生产者的P操作 nq=1
9、; p(s1,nq,currp); else/执行消费者的取商品操作,X:Bout;out:=(out+1)mod 10 coutm=1; break; case 2: if(q=0)/执行生产者的产品上架操作,BIN:produce;IN:=(IN+1)mod 10 coutm=1; else /执行消费者的V操作 nq=1; v(s1,nq,currp); break; case 3: if(q=0)/执行生产者的V操作 nq=2; v(s2,nq,currp); else /执行消费者的consume操作,打印或显示X中的字符 cout消费了一个产品; coutproduce(C,pt)
10、m=1; break; case 4: /返回到L0指令执行 currp-m=1; break; default: ; coutendl; coutw; coutendl; if(w=y|w=Y) producer.m=3; void p(int & s,int p,PCB *d)/P操作 s=s-1; cout测试信号量spendl; if(sm=2; d-waitreason=p; coutp_name进入等待; else coutp_namem=1; void v(int & s,int p,PCB *d)/V操作 s=s+1; if(sp_name,producer)=0) cout释
11、放进程customer; else cout释放进程producer; else coutm=1; void main( ) initial(); cpuwork(); 五. 实验小结 通过用PV操作解决生产者消费者问题的设计,使我更加深刻的了解了PV操作的过程。当进程处于等待态时,在进程控制块PCB中要说明进程等待的原因;当进程处于等待态或就绪态时,PCB中保留了断点信息,一旦进程再度占有处理器,则就从断点位置继续运行;当进程处于完结状态,表示进程执行结束。在这次实验中,巩固了C语言编程知识,并且对用同步机构避免并发进程执行时可能出现的与时间有关的错误,及对PV操作的状况有了更形象的认识。
copyright@ 2008-2023 冰点文库 网站版权所有
经营许可证编号:鄂ICP备19020893号-2