資源簡介
實驗題目: 生產者與消費者(綜合性實驗)
實驗環境: C語言編譯器
實驗內容:
① 由用戶指定要產生的進程及其類別,存入進入就緒隊列。
② 調度程序從就緒隊列中提取一個就緒進程運行。如果申請的資源被阻塞則進入相應的等待隊列,調度程序調度就緒隊列中的下一個進程。進程運行結束時,會檢查對應的等待隊列,激活隊列中的進程進入就緒隊列。運行結束的進程進入over鏈表。重復這一過程直至就緒隊列為空。
③ 程序詢問是否要繼續?如果要轉直①開始執行,否則退出程序。
實驗目的:
通過實驗模擬生產者與消費者之間的關系,了解并掌握他們之間的關系及其原理。由此增加對進程同步的問題的了解。
實驗要求:
每個進程有一個進程控制塊(PCB)表示。進程控制塊可以包含如下信息:進程類型標號、進程系統號、進程狀態、進程產品(字符)、進程鏈指針等等。
系統開辟了一個緩沖區,大小由buffersize指定。
程序中有三個鏈隊列,一個鏈表。一個就緒隊列(ready),兩個等待隊列:生產者等待隊列(producer);消費者隊列(consumer)。一個鏈表(over),用于收集已經運行結束的進程
本程序通過函數模擬信號量的操作。
參考書目:
1)徐甲同等編,計算機操作系統教程,西安電子科技大學出版社
2)Andrew S. Tanenbaum著,陳向群,馬紅兵譯. 現代操作系統(第2版). 機械工業出版社
3)Abranham Silberschatz, Peter Baer Galvin, Greg Gagne著. 鄭扣根譯. 操作系統概念(第2版). 高等教育出版社
4)張堯學編著. 計算機操作系統教程(第2版)習題解答與實驗指導. 清華大學出版社
實驗報告要求:
(1) 每位同學交一份電子版本的實驗報告,上傳到202.204.125.21服務器中。
(2) 文件名格式為班級、學號加上個人姓名,例如:
電子04-1-040824101**.doc
表示電子04-1班學號為040824101號的**同學的實驗報告。
(3) 實驗報告內容的開始處要列出實驗的目的,實驗環境、實驗內容等的說明,報告中要附上程序代碼,并對實驗過程進行說明。
基本數據結構:
PCB* readyhead=NULL, * readytail=NULL; // 就緒隊列
PCB* consumerhead=NULL, * consumertail=NULL; // 消費者隊列
PCB* producerhead=NULL, * producertail=NULL; // 生產者隊列
over=(PCB*)malloc(sizeof(PCB)); // over鏈表
int productnum=0; //產品數量
int full=0, empty=buffersize; // semaphore
char buffer[buffersize]; // 緩沖區
int bufferpoint=0; // 緩沖區指針
struct pcb { /* 定義進程控制塊PCB */
int flag; // flag=1 denote producer; flag=2 denote consumer;
int numlabel;
char product;
char state;
struct pcb * processlink;
……
};
processproc( )--- 給PCB分配內存。產生相應的的進程:輸入1為生產者進程;輸入2為消費者進程,并把這些進程放入就緒隊列中。
waitempty( )--- 如果緩沖區滿,該進程進入生產者等待隊列;linkqueue(exe,&producertail); // 把就緒隊列里的進程放入生產者隊列的尾部
void signalempty()
bool waitfull()
void signalfull()
void producerrun()
void comsuerrun()
void main()
{ processproc();
element=hasElement(readyhead);
while(element){
exe=getq(readyhead,&readytail);
printf("進程%d申請運行,它是一個",exe->numlabel);
exe->flag==1? printf("生產者\n"):printf("消費者\n");
if(exe->flag==1)
producerrun();

代碼片段和文件信息
/*
*/
#include
#include
#include
struct?PCB
{???
int?flag; //1為生產者2為消費者
int?numLabel;
};
typedef?struct?QNode
{
PCB?data;//數據域
struct?QNode*?next;//指針域
}QNode?*QueuePtr;
typedef?struct
{
QueuePtr?front;//隊頭指針
QueuePtr?rear;//隊尾指針
}linkQueue;
typedef?struct?LNode
{
QueuePtr?data;
struct?LNode?*next;
}LNode?*linkList;
void?QueueInit(linkQueue&?Q)//初始化隊列
{
Q.front?=?Q.rear?=?(QueuePtr)malloc(sizeof(QNode));
Q.front->next?=?NULL;
}
void?linkListInit(linkList&?L)//初始化鏈表
{
L?=?(linkList)malloc(sizeof(LNode));
}
void?EnQueue(linkQueue&?Q?QueuePtr?p)//入隊
{
p->next?=?NULL;
Q.rear->next?=?p;
Q.rear?=?p;
}
QueuePtr?DeQueue(linkQueue&?Q)//出隊
{
QueuePtr?p?=?Q.front->next;
Q.front->next?=?p->next;
if(Q.rear?==?p)Q.rear?=Q.front;
return?p;
}
void?linkListInsert(linkList&?L?QueuePtr?e)//進入鏈表
{
linkList?p?=?L;
linkList?q?=?(linkList)malloc(sizeof(LNode));
while(p->next)p++;
q->data?=?e;
q->next?=?NULL;
p->next?=?q;
}
void?processproc(linkQueue&?Q)//創建進程進入初始隊列
{
int?processNum?=?0;
cout<<“請輸入進程的個數:“;//確定進程個數,默認為0
cin>>processNum;
for(int?i?=?0;?i? {
cout<<“輸入第“< struct?PCB?pcb;
cin>>pcb.flag;//輸入進程的種類
pcb.numLabel?=?i+1;//進程序號賦值
QueuePtr?p?=?(QueuePtr)malloc(sizeof(QNode));
p->data?=?pcb;
EnQueue(Q?p);
}
}
bool?HasElement(linkQueue?Q)//判斷隊列是否為空
{
if(Q.front?==?Q.rear)return?false;
else?return?true;
}
int?ProduceRun(int&?full?int?BufferSize)//運行生產者進程
{
if(full? {
full++;
return?1;
}
return?0;
}
int?ConsumeRun(int&?full?int?BufferSize)//運行消費者進程
{
if(full?>?0)
{
full--;
return?1;
}
return?0;
}
void?DisPlay(linkQueue?Q)//打印隊列
{
QueuePtr?p?=?Q.front;
while(p->next){
cout<<“進程“<next->data.numLabel< p?=?p->next;
}
}
void?main()
{
int?BufferSize;//設置緩沖區大小
cout<<“請設置緩沖區的大小:?“;
cin>>BufferSize;
????int?full?=?0;//當前緩沖區中的進程數目
int?temp?=?1;
linkList?over;//用于收集已經運行結束的進程
linkListInit(over);
linkQueue?ReadyQueue;//就緒隊列
linkQueue?ProducerWaitQueue;//生產者等待隊列
linkQueue?ConsumerWaitQueue;//消費者等待隊列
//初始化
QueueInit(ReadyQueue);
QueueInit(ProducerWaitQueue);
QueueInit(ConsumerWaitQueue);
while(temp)//死循環
{
processproc(ReadyQueue);//創建進程進入就緒隊列
bool?element=HasElement(ReadyQueue);//判斷隊列是否為空
while(element)//當它不是空的
{
cout<<“進程“<next->data.numLabel<<“申請運行他是一個“;
/********************************************************************/
if(ReadyQueue.front->next->data.flag?==?1)//如果它是一個生產者
{
cout<<“生產者“<
if(ProduceRun(full?BufferSize)?==?1)//判斷緩存區是否還有空間
{
cout<<“進程“<next->data.numLabel<<“執行完畢“< linkListInsert(over?DeQueue(ReadyQueue));//運行結束,進入over鏈表
if(HasElement(ProducerWaitQueue))//檢查生產者等待隊列,激活隊列中的進程進入就緒隊列
EnQueu
?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----
?????文件??????41984??2008-12-27?14:55??sy2\Debug\vc60.idb
?????文件??????61440??2008-12-27?14:55??sy2\Debug\vc60.pdb
?????文件?????259284??2008-12-27?14:55??sy2\Debug\sy2.ilk
?????文件?????217192??2008-12-27?14:55??sy2\Debug\sy2.exe
?????文件?????525312??2008-12-27?14:55??sy2\Debug\sy2.pdb
?????文件??????????0??2008-12-27?14:55??sy2\Debug\sy2.sbr
?????文件?????263384??2008-12-27?14:55??sy2\Debug\sy2.pch
?????文件??????17532??2008-12-27?14:55??sy2\Debug\sy2.obj
?????文件??????74752??2008-12-27?14:55??sy2\Debug\sy2.bsc
?????文件??????41984??2008-12-27?15:06??sy2\sy2.ncb
?????文件????????869??2008-12-27?14:55??sy2\sy2.plg
?????文件???????3369??2008-12-27?14:50??sy2\sy2.dsp
?????文件????????531??2008-12-27?14:50??sy2\sy2.dsw
?????文件??????48640??2008-12-27?15:06??sy2\sy2.opt
?????文件???????5023??2009-01-07?20:35??sy2\sy2.cpp
?????文件??????94208??2009-01-07?20:35??實驗報告2.doc
?????目錄??????????0??2008-12-27?12:23??sy2\Debug
?????目錄??????????0??2008-12-24?08:28??sy2
-----------?---------??----------?-----??----
??????????????1655504????????????????????18
- 上一篇:MyImg2Lcd4.0破解版
- 下一篇:計算機網絡課設之解析ARP數據包
評論
共有 條評論