操作系统提高型实验doc.docx
《操作系统提高型实验doc.docx》由会员分享,可在线阅读,更多相关《操作系统提高型实验doc.docx(23页珍藏版)》请在冰豆网上搜索。
![操作系统提高型实验doc.docx](https://file1.bdocx.com/fileroot1/2023-7/17/4524d191-d5bc-485b-9b05-ee0d90a8f7c3/4524d191-d5bc-485b-9b05-ee0d90a8f7c31.gif)
操作系统提高型实验doc
黄冈师范学院
提高型实验报告
实验课题
生产者和消费者算法实现
(实验类型:
□综合性□设计性□应用性)
实验课程
操作系统
实验时间
2008-12
学生姓名
何银兵
专业班级
软工0602
学号
200626240213
一、实验目的
全面理解生产者与消费者问题模型,掌握解决该问题的算法思想,正确使用同步机制。
二、实验要求
问题描述:
一组生产者向一组消费者提供消息,它们共享一个有界缓冲池,生产者向其中投放消息,消费者从中取得消息。
假定这些生产者和消费者互相等效,只要缓冲池未满,生产者可将消息送入缓冲池;只要缓冲池未空,消费者可从缓冲池取走一个消息。
功能要求:
根据进程同步机制,编写一个解决上述问题的可视化程序,可显示缓冲池状态、放数据、取数据等过程。
具体参数:
有4个生产者进程,分别为P1、P2、P3和P4;有4个消费者进程,分别是C1、C2、C3和C4;缓冲区单元个数N=15
三、实验设备
计算机一台
WINDOWSXPProfessional
Delphi7.0
四、设计流程图
主要流程:
满
否
其它
五、数据定义
MyArray=array[0..14]ofstring;
hcdl,zsdl,jxdl:
MyArray;//定义缓冲队列、阻塞队列和就绪队列,大小为15
functionsta(dl:
MyArray):
string;//函数:
判断指定队列空、满或有值
functionsearchPC(pc:
string;dl:
MyArray):
integer;//函数:
从指定列找出生产者或消费者进程,返回该元素在阻塞队列的序号
functiondlval(dl:
MyArray;pos:
integer):
string;//函数,得到指定队列指定元素的内容,并判断其类型
procedurePC(vardl:
MyArray;pos:
integer);//过程,根据参数所指定的队列和元素进行生产或消费
procedureZS(vardl:
MyArray;pos:
integer);//过程,将指定队列中指定元素送入阻塞队列
六、源程序
unitUnit1;
interface
uses
Windows,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;
GroupBox5:
TGroupBox;
Button1:
TButton;
Edit1:
TEdit;
Label2:
TLabel;
memo1:
TMemo;
BitBtn1:
TBitBtn;
BitBtn2:
TBitBtn;
BitBtn3:
TBitBtn;
Label1:
TLabel;
memo2:
TMemo;
Label3:
TLabel;
procedureButton2Click(Sender:
TObject);
procedureFormActivate(Sender:
TObject);
procedureButton1Click(Sender:
TObject);
procedureBitBtn2Click(Sender:
TObject);
procedureBitBtn1Click(Sender:
TObject);
procedureBitBtn3Click(Sender:
TObject);
private
{Privatedeclarations}
public
{Publicdeclarations}
end;
type
MyArray=array[0..14]ofstring;
var
Form1:
TForm1;
memo1:
TMemo;
memo2:
TMemo;
hcdl,zsdl,jxdl:
MyArray;
steps:
integer=0;
functionsta(dl:
MyArray):
string;
functionsearchPC(pc:
string;dl:
MyArray):
integer;
functiondlval(dl:
MyArray;pos:
integer):
string;
procedurePC(vardl:
MyArray;pos:
integer);
procedureZS(vardl:
MyArray;pos:
integer);
implementation
{$R*.dfm}
procedureTForm1.Button2Click(Sender:
TObject);
begin
self.Close;
end;
procedureTForm1.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;
fori:
=0to14do
begin
hcdl[i]:
='';
zsdl[i]:
='';
jxdl[i]:
='';
listbox1.Items.Add('');
listbox2.Items.Add('');
listbox3.Items.Add('');
end;
end;
procedureTForm1.Button1Click(Sender:
TObject);
var
num,rnd,i:
integer;
begin
ifedit1.text=''then
begin
exit;
end;
num:
=strtoint(edit1.text);
if(num>15)or(num<=0)then
begin
showMessage('请输入1-15的数字!
');
edit1.Clear;
edit1.SetFocus;
end
else
begin
fori:
=0tonum-1do
begin
Randomize;
rnd:
=random(8)+1;
if(rnd>=1)and(rnd<=4)then
jxdl[i]:
='P'+inttostr(rnd)
else
jxdl[i]:
='C'+inttostr(rnd-4);
end;
listbox3.Items.Clear;
fori:
=low(jxdl)tonum-1do
begin
listbox3.Items.Add(jxdl[i]);
end;
steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
随机生成了'+inttostr(num)+'个进程!
');
fori:
=numtohigh(jxdl)do
begin
listbox3.Items.Add('');
end;
end;
bitbtn3.Enabled:
=true;
end;
procedureTForm1.BitBtn2Click(Sender:
TObject);
begin
self.Close;
end;
procedureTForm1.BitBtn1Click(Sender:
TObject);
begin
self.FormActivate(Sender);
end;
procedureTForm1.BitBtn3Click(Sender:
TObject);
var
zsdlsta,hcdlsta,jxdlsta:
string;
jxtop:
string;
begin
zsdlsta:
=sta(zsdl);//判断阻塞队列状态,空与非空
hcdlsta:
=sta(hcdl);//判断缓冲池状态
jxdlsta:
=sta(jxdl);
jxtop:
=dlval(jxdl,0);//判断就绪队列第一个进程的类型
ifzsdlsta<>'empty'then
begin
{steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
阻塞队列不为空');
}
ifhcdlsta='empty'then//缓冲为空,需要生产者
begin//showmessage('在阻塞中找生产者--生产,找不到就从就绪队列
//拿第一个元素生产/消费,若就绪为空,结束');
ifsearchPC('P',zsdl)<>-1then
begin
steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
在阻塞队列中找到生产者');
//生产
PC(zsdl,searchPC('P',zsdl));
end
elseifjxdlsta<>'empty'then//就绪队列不为空
begin
steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
阻塞队列中无生产者');
//查看就绪队列第一个进程');
ifjxtop='P'then
begin
steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
就绪队列第一个进程是生产,生产');
PC(jxdl,0);
end
elseifjxtop='C'then
begin
steps:
=steps+1;
memo2.Lines.Add(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
elseifhcdlsta='full'then//缓冲满,需要消费者
begin
steps:
=steps+1;
//showmessage('在阻塞中找消费者--消费,找不到就从就绪队列拿第一个元素生产/消费,若就绪为空,结束');
ifsearchPC('C',zsdl)<>-1then
begin
steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
在阻塞队列中找到消费者');
//消费
PC(zsdl,searchPC('C',zsdl));
end
else
ifjxdlsta<>'empty'then//就绪队列不为空
begin
steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
阻塞队列中无消费者');//查看就绪队列第一个进程');
ifjxtop='P'then
begin
steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
就绪队列第一个进程是生产,阻塞');
ZS(jxdl,0);
end
elseifjxtop='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)+':
程序出错-就绪队列中出现的非法进程!
');
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
end
elseifzsdlsta='empty'then
begin//阻塞为空,就从就绪队列拿一个
{steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
阻塞队列为空');}
ifjxdlsta<>'empty'then//就绪队列不为空,可以从里面拿
begin
ifhcdlsta='empty'then
begin
ifjxtop='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)+':
就绪队列第一个进程是消费,阻塞');
ZS(jxdl,0);
end;
end
elseifhcdlsta='full'then
begin
ifjxtop='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
ifjxtop='P'then
begin
steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
就绪队列第一个进程是生产,生产');
PC(jxdl,0);
end
elseifjxtop='C'then
begin
steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
就绪队列第一个进程是消费,消费');
PC(jxdl,0);
end;
end;
end
else//就绪队列为为空,程序结束
begin
steps:
=steps+1;
memo2.Lines.Add(inttostr(steps)+':
无任何进程可运行,程序结束!
');
exit;
end
end;
end;
//////////////////////////////////////////////////////////
//函数:
判断指定队列空、满或有值
functionsta(dl:
MyArray):
string;
var
notfull,notempty:
integer;
i:
integer;
begin
notfull:
=0;
notempty:
=0;
fori:
=0to14do
begin
ifdl[i]=''then
notfull:
=1
else
notempty:
=1;
end;
if(notfull=1)and(notempty=0)then
result:
='empty'
elseif(notfull=0)and(notempty=1)then
result:
='full'
elseif(notfull=1)and(notempty=1)then
result:
='ok';
end;
//函数:
从指定列找出生产者或消费者进程,返回该元素在阻塞队列的序号
functionsearchPC(pc:
string;dl:
MyArray):
integer;
var
i:
integer;
begin
result:
=-1;
fori:
=0to14do
begin
ifleftstr(dl[i],1)=pcthen
begin
result:
=i;
exit;
end;
end;
//SHOWMESSAGE('阻塞队列无需要的进程');
end;
//函数,得到指定队列指定元素的内容,并判断其类型
functiondlval(dl:
MyArray;pos:
integer):
string;
begin
ifleftstr(dl[pos],1)='P'then
result:
='P'
elseifleftstr(dl[pos],1)='C'then
result:
='C';
end;
//过程,根据参数所指定的队列和元素进行生产或消费
procedurePC(vardl:
MyArray;pos:
integer);
var
i,t:
integer;
begin
ifleftstr(dl[pos],1)='P'then
begin
steps:
=steps+1;
form1.memo2.Lines.Add(inttostr(steps)+':
'+dl[pos]+'生产一个,缓冲加一,队列减一');
fori:
=0to14do
begin
ifhcdl[i]=''then
begin
hcdl[i]:
=dl[pos];
steps:
=steps+1;
form1.memo2.Lines.Add(inttostr(steps)+':
'+dl[pos]+'生产:
'+hcdl[i]);
form1.listbox1.Items.Clear;
fort:
=0to14do//在列表显示出来
begin
form1.listbox1.Items.Add(hcdl[t]);
end;
fort:
=posto13do
begin
dl[t]:
=dl[t+1];//队列中撤消进程
dl[t+1]:
='';
end;
//showmessage(dl[pos]);
form1.listbox3.Items.Clear;
fort:
=0to14do//在列表显示出来
begin
form1.listbox3.Items.Add(dl[t]);
end;
exit;//退出
end;
end;
end
elseifleftstr(dl[pos],1)='C'then
begin
steps:
=steps+1;
form1.memo2.Lines.Add(inttostr(steps)+':
'+dl[pos]+'消费一个,缓冲减一,队列减一');
fori:
=0to14do
begin
ifhcdl[i]<>''then
begin
form1.memo1.Lines.Add(dl[pos]+'消费:
'+hcdl[i]);
fort:
=posto13do
begin
hcdl[t]:
=hcdl[t+1];//队列中撤消进程
hcdl[t+1]:
='';
dl[t]:
=dl[t+1];
dl[t+1]:
='';
end;
form1.ListBox1.Items.Clear;//更新列表框
form1.ListBox2.Items.Clear;
form1.ListBox3.Items.Clear;
fort:
=0to14do
begin
form1.ListBox1.Items.Add(hcdl[t]);
form1.ListBox2.Items.Add(zsdl[t]);
form1.ListBox3.Items.Add(jxdl[t]);
end;
exit;
end;
end;
end;
end;
//过程,将指定队列中指定元素送入阻塞队列
procedureZS(vardl:
MyArray;pos:
integer);
var
i,t:
integer;
begin
fori:
=0to14do
begin
ifzsdl[i]=''then
begin
zsdl[i]:
=dl[pos];//加入阻塞
fort:
=posto13do
begin
dl[t]:
=dl[t+1];//队列中撤消进程
dl[t+1]:
='';
end;
form1.ListBox1.Items.Clear;//更新列表框
form1.ListBox2.Items.Clear;
form1.ListBox3.Items.Clear;
fort:
=0to14do
begin
form1.ListBox1.Items.Add(hcdl[t]);
form1.ListBox2.Items.Add(zsdl[t]);
form1.ListBox3.Items.Add(jxdl[t]);
end;
exit;
end;
end;
end;
//