1、操作系统提高型实验doc黄冈师范学院提高型实验报告实验课题 生产者和消费者算法实现(实验类型:综合性 设计性 应用性)实验课程操作系统实验时间2008-12学生姓名何银兵专业班级软工0602学 号200626240213一、实验目的全面理解生产者与消费者问题模型,掌握解决该问题的算法思想,正确使用同步机制。二、实验要求问题描述:一组生产者向一组消费者提供消息,它们共享一个有界缓冲池,生产者向其中投放消息,消费者从中取得消息。假定这些生产者和消费者互相等效,只要缓冲池未满,生产者可将消息送入缓冲池;只要缓冲池未空,消费者可从缓冲池取走一个消息。功能要求:根据进程同步机制,编写一个解决上述问题的可
2、视化程序,可显示缓冲池状态、放数据、取数据等过程。具体参数:有4个生产者进程,分别为P1、P2、P3和P4;有4个消费者进程,分别是C1、C2、C3和C4;缓冲区单元个数N=15三、实验设备 计算机一台 WINDOWS XP Professional Delphi 7.0四、设计流程图主要流程:满否其它五、数据定义MyArray=array0.14 of string;hcdl,zsdl,jxdl:MyArray; /定义缓冲队列、阻塞队列和就绪队列,大小为15function sta(dl:MyArray):string; /函数:判断指定队列空、满或有值function searchPC(
3、pc:string;dl:MyArray):integer; / 函数:从指定列找出生产者或消费者进程,返回该元素在阻塞队列的序号function dlval(dl:MyArray;pos:integer):string; /函数,得到指定队列指定元素的内容,并判断其类型procedure PC(var dl:MyArray;pos:integer); /过程,根据参数所指定的队列和元素进行生产或消费procedure ZS(var dl:MyArray;pos:integer); /过程,将指定队列中指定元素送入阻塞队列六、源程序unit Unit1;interfaceuses Window
4、s, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, ComCtrls, Buttons,StrUtils;type TForm1 = class(TForm) GroupBox1: TGroupBox; GroupBox2: TGroupBox; GroupBox3: TGroupBox; ListBox1: TListBox; ListBox2: TListBox; ListBox3: TListBox; GroupBox4: TGroupBox;
5、GroupBox5: TGroupBox; Button1: TButton; Edit1: TEdit; Label2: TLabel; memo1: TMemo; BitBtn1: TBitBtn; BitBtn2: TBitBtn; BitBtn3: TBitBtn; Label1: TLabel; memo2: TMemo; Label3: TLabel; procedure Button2Click(Sender: TObject); procedure FormActivate(Sender: TObject); procedure Button1Click(Sender: TOb
6、ject); procedure BitBtn2Click(Sender: TObject); procedure BitBtn1Click(Sender: TObject); procedure BitBtn3Click(Sender: TObject); private Private declarations public Public declarations end;type MyArray=array0.14 of string;var Form1: TForm1; memo1: TMemo; memo2: TMemo; hcdl,zsdl,jxdl:MyArray; steps:
7、integer=0; function sta(dl:MyArray):string; function searchPC(pc:string;dl:MyArray):integer; function dlval(dl:MyArray;pos:integer):string; procedure PC(var dl:MyArray;pos:integer); procedure ZS(var dl:MyArray;pos:integer); implementation$R *.dfmprocedure TForm1.Button2Click(Sender: TObject);beginse
8、lf.Close;end;procedure TForm1.FormActivate(Sender: TObject);var i:integer;begin listbox1.Items.Clear; listbox2.Items.Clear; listbox3.Items.Clear; memo1.Clear; memo2.Clear; edit1.Clear; bitbtn3.Enabled:=false; steps:=0; for i:=0 to 14 do begin hcdli:=; zsdli:=; jxdli:=; listbox1.Items.Add(); listbox2
9、.Items.Add(); listbox3.Items.Add(); end; end;procedure TForm1.Button1Click(Sender: TObject); var num,rnd,i:integer;begin if edit1.text= then begin exit; end; num:=strtoint(edit1.text); if (num15) or (num=1)and (rnd=4) then jxdli:=P+inttostr(rnd) else jxdli:=C+inttostr(rnd-4); end; listbox3.Items.Cle
10、ar; for i:=low(jxdl) to num-1 do begin listbox3.Items.Add(jxdli); end; steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:随机生成了+inttostr(num)+个进程!); for i:=num to high(jxdl) do begin listbox3.Items.Add(); end; end; bitbtn3.Enabled:=true;end;procedure TForm1.BitBtn2Click(Sender: TObject);beginself.Clos
11、e;end;procedure TForm1.BitBtn1Click(Sender: TObject);beginself.FormActivate(Sender);end;procedure TForm1.BitBtn3Click(Sender: TObject);var zsdlsta,hcdlsta,jxdlsta:string; jxtop:string;beginzsdlsta:=sta(zsdl);/判断阻塞队列状态,空与非空hcdlsta:=sta(hcdl);/判断缓冲池状态jxdlsta:=sta(jxdl);jxtop:=dlval(jxdl,0);/判断就绪队列第一个进
12、程的类型if zsdlstaempty then begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:阻塞队列不为空); if hcdlsta=empty then /缓冲为空,需要生产者 begin / showmessage(在阻塞中找生产者-生产,找不到就从就绪队列/拿第一个元素生产/消费,若就绪为空,结束); if searchPC(P,zsdl)-1 then begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:在阻塞队列中找到生产者); /生产 PC(zsdl,sea
13、rchPC(P,zsdl); end else if jxdlstaempty then /就绪队列不为空 begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:阻塞队列中无生产者); /查看就绪队列第一个进程); if jxtop=P then begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:就绪队列第一个进程是生产,生产); PC(jxdl,0); end else if jxtop=C then begin steps:=steps+1; memo2.Lines.Add(
14、inttostr(steps)+:就绪队列第一个进程是消费,阻塞); ZS(jxdl,0); end else begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:程序出错-就绪队列中出现的非法进程!); exit; end; end else /就绪队列为空 begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:缓冲为空,需要生产者,程序结束); exit; end; end else if hcdlsta=full then /缓冲满,需要消费者 begin steps:=st
15、eps+1; / showmessage(在阻塞中找消费者-消费,找不到就从就绪队列拿第一个元素生产/消费,若就绪为空,结束); if searchPC(C,zsdl)-1 then begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:在阻塞队列中找到消费者); /消费 PC(zsdl,searchPC(C,zsdl); end else if jxdlstaempty then /就绪队列不为空 begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:阻塞队列中无消费者);/查看就
16、绪队列第一个进程); if jxtop=P then begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:就绪队列第一个进程是生产,阻塞); ZS(jxdl,0); end else if jxtop=C then begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:就绪队列第一个进程是消费,消费); PC(jxdl,0); end else begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:程序出错-就绪队列中出现的非
17、法进程!); exit; end; end else /就绪队列为空 begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:缓冲为空,需要消费者,程序结束); exit; end; end else /缓冲区有元素也有空位,则 可生产可消费 begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:运行阻塞队列第一个进程); PC(zsdl,0); end endelse if zsdlsta=empty then begin /阻塞为空 ,就从就绪队列拿一个 steps:=steps+
18、1; memo2.Lines.Add(inttostr(steps)+:阻塞队列为空); if jxdlstaempty then /就绪队列不为空,可以从里面拿 begin if hcdlsta=empty then begin if jxtop=P then begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:就绪队列第一个进程是生产,生产); PC(jxdl,0); end else begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:就绪队列第一个进程是消费,阻塞); Z
19、S(jxdl,0); end; end else if hcdlsta=full then begin if jxtop=C then begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:就绪队列第一个进程是消费,消费); pc(jxdl,0); end else begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:就绪队列第一个进程是生产,阻塞); ZS(jxdl,0); end; end else /缓冲区有元素也有空位,则 可生产可消费 begin if jxtop=P t
20、hen begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:就绪队列第一个进程是生产,生产); PC(jxdl,0); end else if jxtop=C then begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:就绪队列第一个进程是消费,消费); PC(jxdl,0); end; end; endelse /就绪队列为为空,程序结束 begin steps:=steps+1; memo2.Lines.Add(inttostr(steps)+:无任何进程可运行,程序结束!
21、); exit; end end;end; / /函数:判断指定队列空、满或有值 function sta(dl:MyArray):string; var notfull,notempty:integer; i:integer; begin notfull:=0; notempty:=0; for i:=0 to 14 do begin if dli= then notfull:=1 else notempty:=1; end; if (notfull=1) and (notempty=0) then result:=empty else if (notfull=0) and (notempt
22、y=1) then result:=full else if (notfull=1) and (notempty=1) then result:=ok; end; / 函数:从指定列找出生产者或消费者进程,返回该元素在阻塞队列的序号 function searchPC(pc:string;dl:MyArray):integer; var i:integer; begin result:=-1; for i:=0 to 14 do begin if leftstr(dli,1)=pc then begin result:=i; exit; end; end; / SHOWMESSAGE(阻塞队列
23、无需要的进程);end;/函数,得到指定队列指定元素的内容,并判断其类型 function dlval(dl:MyArray;pos:integer):string; begin if leftstr(dlpos,1)=P then result:=P else if leftstr(dlpos,1)=C then result:=C; end; /过程,根据参数所指定的队列和元素进行生产或消费 procedure PC(var dl:MyArray;pos:integer); var i,t:integer; begin if leftstr(dlpos,1)=P then begin st
24、eps:=steps+1; form1.memo2.Lines.Add(inttostr(steps)+:+dlpos+生产一个,缓冲加一,队列减一); for i:=0 to 14 do begin if hcdli= then begin hcdli:=dlpos; steps:=steps+1; form1.memo2.Lines.Add(inttostr(steps)+:+dlpos+生产:+hcdli); form1.listbox1.Items.Clear; for t:=0 to 14 do /在列表显示出来 begin form1.listbox1.Items.Add(hcdl
25、t); end; for t:=pos to 13 do begin dlt:=dlt+1; /队列中撤消进程 dlt+1:=; end; / showmessage(dlpos); form1.listbox3.Items.Clear; for t:=0 to 14 do /在列表显示出来 begin form1.listbox3.Items.Add(dlt); end; exit; /退出 end; end; end else if leftstr(dlpos,1)=C then begin steps:=steps+1; form1.memo2.Lines.Add(inttostr(st
26、eps)+:+dlpos+消费一个,缓冲减一,队列减一) ; for i:=0 to 14 do begin if hcdli then begin form1.memo1.Lines.Add(dlpos+消费:+hcdli); for t:=pos to 13 do begin hcdlt:=hcdlt+1; /队列中撤消进程 hcdlt+1:=; dlt:=dlt+1; dlt+1:=; end; form1.ListBox1.Items.Clear; /更新列表框 form1.ListBox2.Items.Clear; form1.ListBox3.Items.Clear; for t:
27、=0 to 14 do begin form1.ListBox1.Items.Add(hcdlt); form1.ListBox2.Items.Add(zsdlt); form1.ListBox3.Items.Add(jxdlt); end; exit; end; end; end; end;/ 过程,将指定队列中指定元素送入阻塞队列 procedure ZS(var dl:MyArray;pos:integer); var i,t:integer; begin for i:=0 to 14 do begin if zsdli= then begin zsdli:=dlpos; /加入阻塞 f
28、or t:=pos to 13 do begin dlt:=dlt+1; /队列中撤消进程 dlt+1:=; end; form1.ListBox1.Items.Clear; /更新列表框 form1.ListBox2.Items.Clear; form1.ListBox3.Items.Clear; for t:=0 to 14 do begin form1.ListBox1.Items.Add(hcdlt); form1.ListBox2.Items.Add(zsdlt); form1.ListBox3.Items.Add(jxdlt); end; exit; end; end; end; /
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1