生產(chǎn)者消費(fèi)者問題模擬實(shí)現(xiàn)(z)_第1頁
生產(chǎn)者消費(fèi)者問題模擬實(shí)現(xiàn)(z)_第2頁
生產(chǎn)者消費(fèi)者問題模擬實(shí)現(xiàn)(z)_第3頁
生產(chǎn)者消費(fèi)者問題模擬實(shí)現(xiàn)(z)_第4頁
已閱讀5頁,還剩50頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)

文檔簡介

1、生產(chǎn)者消費(fèi)者問題模擬實(shí)現(xiàn)(z)生產(chǎn)者 - 消費(fèi)者實(shí)驗(yàn)1.1 實(shí)驗(yàn)?zāi)康暮鸵髮?shí)驗(yàn)?zāi)康牟僮飨到y(tǒng)的基本控制和管理控制都圍繞著進(jìn)程展開,其中的復(fù)雜性是由于支持并發(fā)和并發(fā)機(jī)制而引起的。自從操作系統(tǒng)中引入并發(fā)程序設(shè)計(jì)后,程序的執(zhí)行不再是順序的, 一個程序未執(zhí)行完而另一個程序便已開始執(zhí)行, 程序外部的順序特性消失, 程序與計(jì)算不再一一對應(yīng)。 并發(fā)進(jìn)程可能是無關(guān)的,也可能是交互的。然而,交互的進(jìn)程共享某些變量, 一個進(jìn)程的執(zhí)行可能會影響其他進(jìn)程的執(zhí)行結(jié)果, 交互的并發(fā)進(jìn)程之間具有制約關(guān)系、 同步關(guān)系。其中典型模型便是生產(chǎn)者- 消費(fèi)者模型。本實(shí)驗(yàn)通過編寫和調(diào)試生產(chǎn)者 - 消費(fèi)者模擬程序,進(jìn)一步認(rèn)識進(jìn)程并發(fā)執(zhí)行的

2、實(shí)質(zhì), 加深對進(jìn)程競爭關(guān)系, 協(xié)作關(guān)系的理解, 掌握使用信號量機(jī)制與 P、V 操作來實(shí)現(xiàn)進(jìn)程的同步與互斥。實(shí)驗(yàn)要求1用高級語言編寫一個程序,模擬多個生圖 3.1 生產(chǎn)者消費(fèi)者問題示意圖著名的生產(chǎn)者消費(fèi)者問題( producer-consumer problem )是計(jì)算機(jī)操作系統(tǒng)中并發(fā)進(jìn)程內(nèi)在關(guān)系的一種抽象, 是典型的進(jìn)程同步問題。 在操作系統(tǒng)中, 生產(chǎn)者進(jìn)程可以是計(jì)算進(jìn)程、 發(fā)送進(jìn)程,而消費(fèi)者進(jìn)程可以是打印進(jìn)程、接收進(jìn)程等, 解決好生產(chǎn)者消費(fèi)者問題就解決了一類并發(fā)進(jìn)程的同步問題。操作系統(tǒng)實(shí)現(xiàn)進(jìn)程同步的機(jī)制稱為同步機(jī)制,它通常由同步原語組成。 不同的同步機(jī)制采用不同的同步方法,迄今已設(shè)計(jì)出多種

3、同步機(jī)制,本實(shí)驗(yàn)采用最常用的同步機(jī)制:信號量及PV操作。信號量與 PV操作1965 年,荷蘭計(jì)算機(jī)科學(xué)家提出新的同步工具信號量和PV操作,他將交通管制中多種顏色的信號燈管理方法引入操作系統(tǒng),讓多個進(jìn)程通過特殊變量展開交互。 一個進(jìn)程在某一關(guān)鍵點(diǎn)上被迫停止直至接收到對應(yīng)的特殊變量值, 通過這一措施任何復(fù)雜的進(jìn)程交互要求均可得到滿足, 這種特殊變量就是信號量(semaphore)。為了通過信號量傳送信號,進(jìn)程可利用 P 和 V 兩個特殊操作來發(fā)送和接收信號,如果協(xié)作進(jìn)程的相應(yīng)信號仍未到達(dá), 則進(jìn)程被掛起直至信號到達(dá)為止。在操作系統(tǒng)中用信號量表示物理資源的實(shí)體,它是一個與隊(duì)列有關(guān)的整型變量。具體實(shí)現(xiàn)

4、時,信號量是一種變量類型, 用一個記錄型數(shù)據(jù)結(jié)構(gòu)表示,有兩個分量:一個是信號量的值,另一個是信號量隊(duì)列的指針。 信號量在操作系統(tǒng)中主要用于封鎖臨界區(qū)、進(jìn)程同步及維護(hù)資源計(jì)數(shù)。除了賦初值之外,信號量僅能由同步原語 PV 對其操作,不存在其他方法可以檢查或操作信號量, PV 操作的不可分割性確保執(zhí)行的原子性及信號量值的完整性。利用信號量和 PV 操作即可解決并發(fā)進(jìn)程競爭問題, 又可解決并發(fā)進(jìn)程協(xié)作問題。信號量按其用途可分為兩種:公用信號量,聯(lián)系一組并發(fā)進(jìn)程, 相關(guān)進(jìn)程均可在此信號量上執(zhí)行 PV操作,用于實(shí)現(xiàn)進(jìn)程互斥; 私有信號量,聯(lián)系一組并發(fā)進(jìn)程, 僅允許此信號量所擁有的進(jìn)程執(zhí)行 P 操作,而其他

5、相關(guān)進(jìn)程可在其上執(zhí)行 V 操作,初值往往為 0 或正整數(shù),多用于并發(fā)進(jìn)程同步。信號量的定義為如下數(shù)據(jù)結(jié)構(gòu):typedef struct semaphoreint value; / struct pcb *list;/信號量的值信號量隊(duì)列的指針信號量說明:semaphore s;P、V 操作原語描述如下:( 1) P(s) :s.value- ;若 s.value 0,則執(zhí)行 P(s) 的進(jìn)程繼續(xù)執(zhí)行;若s.value<0 ,則執(zhí)行 P(s) 的進(jìn)程被阻塞, 并把它插入到等待信號量 s 的阻塞隊(duì)列中。( 2) V(s) :s.value+ ;若 s.value 0,則執(zhí)行 V(s) 的進(jìn)程

6、從等待信號量 s 的阻塞隊(duì)列中喚醒頭一個進(jìn)程,然后自己繼續(xù)執(zhí)行。若 s.value>0 ,則執(zhí)行 V(s) 的進(jìn)程繼續(xù)執(zhí)行;信號量實(shí)現(xiàn)互斥信號量和 PV 操作可用來解決進(jìn)程互斥問題。為使多個進(jìn)程能互斥地訪問某臨界資源, 只需為該資源設(shè)置一互斥信號量 mutex,并置初值為 1,然后將各進(jìn)程訪問該資源的臨界區(qū)置于P(mutex) 和 V(mutex) 操作之間即可。用信號量和 PV操作管理并發(fā)進(jìn)程互斥進(jìn)入臨界區(qū)的一般形式為:semaphore mutex;mutex = 1;cobeginprocess Pi()/*i = 1,2,, n */P(mutex);/*臨界區(qū)*/V(mutex

7、);coend當(dāng)有進(jìn)程在臨界區(qū)中時,mutex 的值為 0 或負(fù)值,否則 mutex 值為 1,因?yàn)橹挥幸粋€進(jìn)程,可用 P 操作把 mutex 減至 0,故可保證互斥操作,這時試圖進(jìn)入臨界區(qū)的其它進(jìn)程會因執(zhí)行 P(mutex) 而被迫等待 。 mutex 的取值范圍是 1-(n-1) ,表明有一個進(jìn)程在臨界區(qū)內(nèi)執(zhí)行, 最多有 n-1 個進(jìn)程在信號量隊(duì)列中等待。信號量解決生產(chǎn)者消費(fèi)者問題信號量和 PV操作不僅可以解決進(jìn)程互斥問題,而且是實(shí)現(xiàn)進(jìn)程同步的有力工具。 在協(xié)作進(jìn)程之間,一個進(jìn)程的執(zhí)行依賴于協(xié)作進(jìn)程的信息或消息,在尚未得到來自協(xié)作進(jìn)程的信號或消息時等待,直至信號或消息到達(dá)時才被喚醒。生產(chǎn)者

8、消費(fèi)者問題是典型的進(jìn)程同步問題,對于生產(chǎn)者進(jìn)程:生產(chǎn)一個產(chǎn)品,當(dāng)要送入緩沖區(qū)時,要檢查是否有空緩沖區(qū),若有,則可將產(chǎn)品送入緩沖區(qū),并通知消費(fèi)者進(jìn)程;否則,等待;對于消費(fèi)者進(jìn)程:當(dāng)它去取產(chǎn)品時,要看緩沖區(qū)中是否有產(chǎn)品可取,若有則取走一個產(chǎn)品,并通知生產(chǎn)者進(jìn)程,否則,等待。這種相互等待,并互通信息就是典型的進(jìn)程同步。因此應(yīng)該設(shè)兩個同步信號量:信號量 empty 表示可用的空緩沖區(qū)的數(shù)目,初值為 k;信號量full表示可以使用產(chǎn)品的數(shù)目,初值為。緩沖區(qū)是一個臨界資源, 必須互斥使用, 所以另外還需要設(shè)置一個互斥信號量 mutex,其初值為。用信號量機(jī)制解決生產(chǎn)者消費(fèi)者問題可描述如下:item Bk;

9、semaphore empty; empty=k; /可以使用的空緩沖區(qū)數(shù)semaphore full;full=0;/緩沖區(qū)內(nèi)可以使用的產(chǎn)品數(shù)semaphore mutex; mutex=1; /互斥信號量int in=0;int out=0;/放入緩沖區(qū)指針取出緩沖區(qū)指針cobeginprocess producer_i()process consumer()While(true)While(true)produce();P(full);P(empty);P(mutex);P(mutex);take from Bout;append to Bin;out =(out+1)%k;in = (

10、in+1)%k;V(mutex);V(mutex);V(empty);V(full);consume();Coend程序中的 P(mutex) 和 V(mutex) 必須成對出現(xiàn),夾在兩者之間的代碼段是臨界區(qū); 施加于信號量 empty 和 full 上的 PV 操作也必須成對出現(xiàn),但分別位于不同的程序中。 在生產(chǎn)者消費(fèi)者問題中, P 操作的次序是很重要的,如果把生產(chǎn)者進(jìn)程中的兩個 P 操作交換次序, 那么,當(dāng)緩沖區(qū)中存滿 k 件產(chǎn)品時,生產(chǎn)者又生產(chǎn)一件產(chǎn)品,在它欲向緩沖區(qū)存放時,將在 P(empty) 上等待,由于此時 mutex=0,它已經(jīng)占有緩沖區(qū),這時消費(fèi)者預(yù)取產(chǎn)品時將停留在 P(mu

11、tex) 上而得不到使用緩沖區(qū)的權(quán)力。 這就導(dǎo)致生產(chǎn)者等待消費(fèi)者取走產(chǎn)品,而消費(fèi)者卻在等待生產(chǎn)者釋放緩沖區(qū)的占有權(quán),這種互相之間的等待永遠(yuǎn)不可能結(jié)束。所以,在使用信號量和PV 操作實(shí)現(xiàn)進(jìn)程同步時,特別要當(dāng)心 P 操作的次序, 而 V 操作的次序無關(guān)緊要。 一般來說,用于互斥的信號量上的P 操作總是在后面執(zhí)行。Q 所1.2 生產(chǎn)者消費(fèi)者問題模擬實(shí)現(xiàn)實(shí)驗(yàn)內(nèi)容考慮一個系統(tǒng)中有 n 個進(jìn)程,其中部分進(jìn)程為生產(chǎn)者進(jìn)程, 部分進(jìn)程為消費(fèi)者進(jìn)程, 共享具有 k 個單位的緩沖區(qū)。現(xiàn)要求用高級語言編寫一個程序, 模擬多個生產(chǎn)者進(jìn)程和多個消費(fèi)者進(jìn)程并發(fā)執(zhí)行的過程,并采用信號量機(jī)制與 P、V 操作實(shí)現(xiàn)生產(chǎn)者進(jìn)程和消

12、費(fèi)者進(jìn)程間同步以及對緩沖區(qū)的互斥訪問。利用信號量機(jī)制解決此問題的算法見示。實(shí)驗(yàn)指導(dǎo)1設(shè)計(jì)提示( 1)本實(shí)驗(yàn)并不需要真正創(chuàng)建生產(chǎn)者和消費(fèi)者進(jìn)程,每個進(jìn)程用一個進(jìn)程控制塊( PCB)表示。 PCB數(shù)據(jù)結(jié)構(gòu)如下:typedef struct Process/進(jìn)程PCBchar name10;int roleFlag;/ 進(jìn)程名/進(jìn)程類型(1:生產(chǎn)者0:消費(fèi)者)int currentState;/進(jìn)程狀態(tài)( 1:可運(yùn)行態(tài)0:int currentStep;阻塞態(tài))/ 斷點(diǎn)int data;/ / 臨時數(shù)據(jù)/進(jìn)程編號Process;(2)程序中應(yīng)指定緩沖區(qū)的數(shù)目,進(jìn)程總個數(shù)等,現(xiàn)考慮共有 4 個生產(chǎn)者和

13、消費(fèi)者進(jìn)程,緩沖區(qū)數(shù)目是兩個,定義如下所示:#define dataBufferSize 2/緩沖區(qū)數(shù)目#define processNum 4/進(jìn)程數(shù)量(生產(chǎn)者、消費(fèi)者進(jìn)程總數(shù)目)struct DataBuffer/緩沖區(qū)i nt bufferdataBufferSize;i nt count;/ 當(dāng)前產(chǎn)品數(shù)量 dataBuffer;( 3)為解決生產(chǎn)者 - 消費(fèi)者問題需設(shè)兩個同步信號量:信號量 empty 表示可用的空緩沖區(qū)的數(shù)目,初值為緩沖區(qū)數(shù)目;信號量 full 表示可以使用產(chǎn)品的數(shù)目, 初值為。緩沖區(qū)是一個臨界資源,必須互斥使用, 所以另外還需要設(shè)置一個互斥信號量 mutex,其初值

14、為。信號量定義和說明如下所示:typedef struct Seamphore/信號量int value;int *pcq;/ 信號量的值/ 信號量隊(duì)列指針 Seamphore;intproducerCongestionQueueprocessNum;/ / 等待信號量 empty 的阻塞隊(duì)列intconsumerCongestionQueueprocessNum;/ / 等待信號量 full 的阻塞隊(duì)列int shareCongestionQueueprocessNum;/ 等待信號量 mutex 的阻塞隊(duì)列Seamphoreempty=dataBufferSize,producerCong

15、estionQueue;Seamphorefull=0,consumerCongestionQueue;Seamphoremutex=1,shareCongestionQueue;( 4)為模擬多個生產(chǎn)者和多個消費(fèi)者進(jìn)程并發(fā)執(zhí)行的過程, 首先根據(jù)進(jìn)程總個數(shù)產(chǎn)生若干生產(chǎn)者和若干消費(fèi)者進(jìn)程, 然后隨機(jī)調(diào)度一個處于就緒態(tài)的進(jìn)程, 判斷是生產(chǎn)者還是消費(fèi)者, 然后執(zhí)行不同的代碼, 為模擬并發(fā)執(zhí)行, 進(jìn)程每執(zhí)行一步操作就中斷執(zhí)行,再調(diào)度其他進(jìn)程運(yùn)行,在被中斷進(jìn)程的 PCB中記錄了中斷的位置, 等到下次被調(diào)度執(zhí)行時則從此位置繼續(xù)執(zhí)行。(5)生產(chǎn)者進(jìn)程執(zhí)行時分為6 步,如下所示:void produce(Pr

16、ocess *p)/ / 生產(chǎn)者進(jìn)程執(zhí)行代碼switch (p->currentStep) case 1:/1生產(chǎn)產(chǎn)品p->data = rand()%1000;printf("%20s:生產(chǎn)一個產(chǎn)品%d!n",p->name, p->data);p->currentStep+;break;case 2:/2申請空緩沖區(qū)P(&empty, p);break;case 3:/3申請?jiān)L問緩沖區(qū)P(&mutex, p);break;case 4:/4將產(chǎn)品送入緩沖區(qū)push(p->data);printf("%20s:

17、將產(chǎn)品 %d 正送入緩沖區(qū)!n", p->name, p->data);p->currentStep+;break;case 5:/5釋放緩沖區(qū)訪問權(quán)V(&mutex, p);break;case 6:/6產(chǎn)品已送入緩沖區(qū),產(chǎn)品數(shù)量加1V(&full, p);p->currentStep = 1;break;( 6)消費(fèi)者進(jìn)程執(zhí)行時也分為 6 步,如下所示:void consume(Process *p)/消 費(fèi)者進(jìn)程執(zhí)行代碼switch (p->currentStep) case 1:/1申請從緩沖區(qū)取出產(chǎn)品P(&full, p

18、);break;case 2:/2申請?jiān)L問緩沖區(qū)P(&mutex, p);break;case 3:/3從緩沖區(qū)中取出產(chǎn)品p->data = pop();printf("%20s:從緩沖區(qū)中正取出產(chǎn)品 %d!n", p->name, p->data);p->currentStep+;break;case 4:/4釋放緩沖區(qū)訪問權(quán)V(&mutex, p);break;case 5:/ /5已 從緩沖區(qū)取出一個產(chǎn)品,空緩沖區(qū)數(shù)量加1V(&empty, p);break;case 6:/ /6消 費(fèi)產(chǎn)品printf("%2

19、0s: 消 費(fèi) 產(chǎn) 品 %d!n", p->name, p->data);p->currentStep = 1;break;( 6)為對生產(chǎn)者進(jìn)程和消費(fèi)者進(jìn)程并發(fā)執(zhí)行的過程進(jìn)行分析,理解信號量和 P、V 操作在進(jìn)程同步和互斥機(jī)制中的運(yùn)用, 要求進(jìn)程每執(zhí)行一步都輸出每一步的執(zhí)行情況。2程序流程圖(1)程序流程圖如圖3.2 所示:開始初始化緩沖區(qū)和信號量創(chuàng)建若干生產(chǎn)者進(jìn)程和若干消費(fèi)者進(jìn)程隨機(jī)選取一個就緒狀態(tài)進(jìn)程YN該進(jìn)程是生產(chǎn)者?生產(chǎn)者進(jìn)程執(zhí)行一步操作消費(fèi)者進(jìn)程執(zhí)行一步操作記錄中斷位置圖 3.2 程序流程圖( 2)生產(chǎn)者進(jìn)程和消費(fèi)者進(jìn)程執(zhí)行時各有6 步操作,執(zhí)行一個操作

20、后會被中斷,下次再被調(diào)度執(zhí)行時接著執(zhí)行下一操作。 生產(chǎn)者進(jìn)程流程圖如圖 3.3 所示,消費(fèi)者進(jìn)程流程圖如圖 3.4 所示。開始1:生產(chǎn)產(chǎn)品2:P(empty)3:P(mutex)4:將產(chǎn)品送入緩沖區(qū)5:V(mutex)6:V(full)開始1:P(full)2:P(mutex)3:從緩沖區(qū)取一個產(chǎn)品4:V(mutex)5:V(full)6:消費(fèi)產(chǎn)品圖 2.2生產(chǎn)者進(jìn)程流程圖圖 2.3消費(fèi)者進(jìn)程流程圖程序示例#include "stdio.h"#include "time.h"#include "stdlib.h"#include &q

21、uot;string.h"#include "windows.h"#define dataBufferSize 2/ 緩沖區(qū)數(shù)目#define processNum 4/ 進(jìn)程數(shù)量 ( 生產(chǎn)者、消費(fèi)者進(jìn)程總數(shù)目)typedef struct Seamphore/信號量int value;/ 信號量的值int *pcq;/ 信號量隊(duì)列指針 Seamphore;int producerCongestionQueueprocessNum;/ 等待信號量 empty 的阻塞隊(duì)列int consumerCongestionQueueprocessNum;/ 等待信號量 fu

22、ll 的阻塞隊(duì)列int shareCongestionQueueprocessNum;/ 等待信號量 mutex 的阻塞隊(duì)列Seamphoreempty=dataBufferSize,producerCongestionQueue; / empty:空緩沖區(qū)數(shù)目Seamphorefull=0,consumerCongestionQueue;/full:緩沖區(qū)內(nèi)可用的產(chǎn)品Seamphore mutex=1,shareCongestionQueue;/mutex :互斥信號量struct DataBuffer/緩沖區(qū)int bufferdataBufferSize;int count;/ 當(dāng)前產(chǎn)品

23、數(shù)量 dataBuffer;typedef struct Process/進(jìn)程PCBchar name10;int roleFlag;/ 進(jìn)程名/進(jìn)程類型(1:生產(chǎn)者消費(fèi)者)int currentState;/進(jìn)程狀態(tài)(1:就緒態(tài)0:阻塞態(tài))int currentStep;int data;int code;/斷點(diǎn)/臨時數(shù)據(jù)/進(jìn)程編號Process;Process processprocessNum; /進(jìn)程集合void moveDataForward()int i;for (i = 0; i < dataBuffer.count; i+)dataBuffer.bufferi =data

24、Buffer.bufferi+1;void push(int data)/產(chǎn)品送入緩沖區(qū)dataBuffer.bufferdataBuffer.count+ =data;int pop()/從緩沖區(qū)取出產(chǎn)品int data = dataBuffer.buffer0;dataBuffer.count-;moveDataForward();return data;void initProcess() int i;char digitTemp5;srand(time(NULL);/ 初始化進(jìn)程集合for (i = 0; i < processNum; i+) processi.roleFlag

25、 = rand()%2;/ 隨機(jī)指定當(dāng)前進(jìn)程為生產(chǎn)者或消費(fèi)者if (processi.roleFlag)strcpy(, "生產(chǎn)者 ");elsestrcpy(, " 消費(fèi)者 "); strcat(, itoa(i+1,digitTemp, 10);processi.currentState = 1;processi.currentStep = 1;processi.code = i + 1;producerCongestionQueuei = 0; consumerConge

26、stionQueuei = 0; shareCongestionQueuei = 0;void wakeup(int *pcq) / 喚醒進(jìn)程int code = pcq0 - 1;/ 取出隊(duì)首進(jìn)程processcode.currentState = 1;/進(jìn)程置為就緒態(tài)/ 當(dāng)進(jìn)程被喚醒后繼續(xù)執(zhí)行任務(wù)if (processcode.roleFlag = 1) / 生產(chǎn)者if (processcode.currentStep = 2)printf("%20s:該進(jìn)程被喚醒 ! 申請空緩沖區(qū)成功 !n", ); else if(processco

27、de.currentStep=3)printf("%20s:該進(jìn)程被喚醒 ! 申請?jiān)L問緩沖區(qū)成功 !n", ); else if(processcode.roleFlag= 0) / 消費(fèi)者if (processcode.currentStep = 1)processcode.data = pop(); printf("%20s: 該進(jìn)程被喚醒 ! 申請取產(chǎn)品 %d成功 !n", ,processcode.data); else if(processcode.currentStep=2)pr

28、intf("%20s:該進(jìn)程被喚醒 ! 申請?jiān)L問緩沖區(qū)成功 !n", );processcode.currentStep+;for (int i = 1; (i < processNum) &&(pcqi != 0); i+) / 刪除隊(duì)首進(jìn)程 pcqi-1 = pcqi;if (pcqi-1 > processNum) pcqi-1 = 0;pcqi-1 = 0;void sleep(int pcq, int code) /阻塞進(jìn)程int i;processcode-1.currentState = 0;/ 進(jìn)程

29、置為阻塞態(tài)for (i = 0; i < processNum; i+) if (!pcqi) pcqi = code;break;void P(Seamphore *s, Process *p) / 模擬 P操作s->value -= 1;if (s->value>= 0) if (p->roleFlag = 1) /生產(chǎn)者if (p->currentStep = 2) printf("%20s: 申請空緩沖區(qū)成功!n", p->name); else if (p->currentStep = 3) printf("

30、;%20s: 申請?jiān)L問緩沖區(qū)成功!n", p->name); else if (p->roleFlag = 0) / 消費(fèi)者if (p->currentStep = 1) printf("%20s: 申請取出產(chǎn)品成功!n", p->name); else if (p->currentStep = 2) printf("%20s: 申請?jiān)L問緩沖區(qū)成功!n", p->name);p->currentStep+;/ 下一步 else if (s->value < 0) if (p->role

31、Flag = 1) /生產(chǎn)者if (p->currentStep = 2) printf("%20s:無空緩沖區(qū) ,該進(jìn)程被阻塞 !n", p->name); else if (p->currentStep = 3) printf("%20s:其他進(jìn)程正在訪問緩沖區(qū) ,該進(jìn)程被阻塞 !n", p->name); else if (p->roleFlag = 0) / 消費(fèi)者if (p->currentStep = 1) printf("%20s:無產(chǎn)品可取 ,該進(jìn)程被阻塞 !n", p->na

32、me); else if (p->currentStep = 2) printf("%20s: 其他進(jìn)程正在訪問緩沖區(qū) ,該進(jìn)程被阻塞 !n", p->name);sleep(s->pcq, p->code);/ 阻塞進(jìn)程void V(Seamphore *s, Process *p) 產(chǎn)品已送入緩沖區(qū),產(chǎn)品/ 模擬 V操作s->value += 1;if (p->roleFlag = 1) / 生產(chǎn)者if (p->currentStep = 5) printf("%20s: 釋放緩沖區(qū)訪問權(quán) !n", p-&g

33、t;name); else if (p->currentStep = 6) printf("%20s:數(shù)量增加 !n", p->name); else if (p->roleFlag = 0) /消費(fèi)者if (p->currentStep = 4) printf("%20s: 釋放緩沖區(qū)訪問權(quán) !n", p->name); else if (p->currentStep = 5) printf("%20s: 產(chǎn)品已取出,空緩沖區(qū)數(shù)量增加 !n", p->name);if (s->valu

34、e<= 0) wakeup(s->pcq);p->currentStep+;void produce(Process *p) / 模擬生產(chǎn)者進(jìn)程switch (p->currentStep) case 1:/1生產(chǎn)產(chǎn)品p->data = rand()%1000;printf("%20s:生產(chǎn)一個產(chǎn)品 %d!n",p->name, p->data);p->currentStep+;break;case 2:/2申請空緩沖區(qū)P(&empty, p);break;case 3:/3申請?jiān)L問緩沖區(qū)P(&mutex, p

35、);break;case 4:/4將產(chǎn)品送入緩沖區(qū)push(p->data);printf("%20s:將產(chǎn)品 %d正送入緩沖區(qū)!n", p->name, p->data); p->currentStep+;break;case 5:/5釋放緩沖區(qū)訪問權(quán)V(&mutex, p);break;case 6:/6產(chǎn)品已送入緩沖區(qū),產(chǎn)品數(shù)量加1V(&full, p);p->currentStep = 1;break;void consume(Process *p) / 模擬消費(fèi)者進(jìn)程switch (p->currentStep)

36、 case 1:/1申請從緩沖區(qū)取出產(chǎn)品P(&full, p);break;case 2:/2申請?jiān)L問緩沖區(qū)P(&mutex, p);break;case 3:/3從緩沖區(qū)中取出產(chǎn)品p->data = pop();printf("%20s:從緩沖區(qū)中正取出產(chǎn)品%d!n", p->name, p->data); p->currentStep+;break;case 4:/4釋放緩沖區(qū)訪問權(quán)V(&mutex, p);break;case 5:/5已從緩沖區(qū)取出一個產(chǎn)品,空緩沖區(qū)數(shù)量加1V(&empty, p);break;

37、case 6:/6消費(fèi)產(chǎn)品printf("%20s: 消費(fèi)產(chǎn)品 %d!n", p->name, p->data);p->currentStep = 1;break;void rr() Process *p;while(1) / 模擬進(jìn)程調(diào)度p = &processrand()%processNum;/ 隨機(jī)選取進(jìn)程集合內(nèi)某一進(jìn)程if (!p->currentState) /選取的進(jìn)程若為阻塞態(tài), 重新選取其它可執(zhí)行進(jìn)程continue;if (p->roleFlag) /1:生產(chǎn)者0: 消費(fèi)者produce(p); else consu

38、me(p);Sleep(100);void deal() printf("tt生產(chǎn)者消費(fèi)者算法模擬nn");initProcess();rr();int main () deal();return 0;運(yùn)行結(jié)果及分析1. 運(yùn)行結(jié)果程序經(jīng)編譯運(yùn)行后,輸出如下結(jié)果:生產(chǎn)者消費(fèi)者算法模擬消費(fèi)者 2:無產(chǎn)品可取 ,該進(jìn)程被阻塞 !生產(chǎn)者 3:生產(chǎn)一個產(chǎn)品 344!生產(chǎn)者 3:申請空緩沖區(qū)成功 !生產(chǎn)者 1:生產(chǎn)一個產(chǎn)品 723!生產(chǎn)者 1:申請空緩沖區(qū)成功 !生產(chǎn)者 3:申請?jiān)L問緩沖區(qū)成功 !生產(chǎn)者 3:將產(chǎn)品 344 正送入緩沖區(qū) !生產(chǎn)者 3:釋放緩沖區(qū)訪問權(quán) !生產(chǎn)者 1:申

39、請?jiān)L問緩沖區(qū)成功 !生產(chǎn)者 1:將產(chǎn)品 723 正送入緩沖區(qū) !生產(chǎn)者 3:產(chǎn)品已送入緩沖區(qū),產(chǎn)品數(shù)量增加 !消費(fèi)者 2:該進(jìn)程被喚醒 ! 申請取產(chǎn)品 344 成功 !消費(fèi)者 4:無產(chǎn)品可取 ,該進(jìn)程被阻塞 !生產(chǎn)者 1:釋放緩沖區(qū)訪問權(quán) !消費(fèi)者 2:申請?jiān)L問緩沖區(qū)成功 !消費(fèi)者 2:從緩沖區(qū)中正取出產(chǎn)品 723!生產(chǎn)者 3:生產(chǎn)一個產(chǎn)品 924!消費(fèi)者 2:釋放緩沖區(qū)訪問權(quán) !生產(chǎn)者 1:產(chǎn)品已送入緩沖區(qū),產(chǎn)品數(shù)量增加 !消費(fèi)者 4:該進(jìn)程被喚醒 ! 申請取產(chǎn)品 723 成功 !生產(chǎn)者 1:生產(chǎn)一個產(chǎn)品 510!生產(chǎn)者 1:無空緩沖區(qū) ,該進(jìn)程被阻塞 !消費(fèi)者 2:產(chǎn)品已取出,空緩沖區(qū)數(shù)量增加 !生產(chǎn)者 1:該進(jìn)程被喚醒 ! 申請空緩沖區(qū)成功 !生產(chǎn)者 1:申請?jiān)L問緩沖區(qū)成功 !消費(fèi)者 4: 其他進(jìn)程正在訪問緩沖區(qū) , 該進(jìn)程被阻塞 !生產(chǎn)者 3:無空緩沖區(qū) ,該進(jìn)程被阻塞 !生產(chǎn)者 1:將產(chǎn)品 510 正送入緩沖區(qū) !生產(chǎn)者 1:釋放緩沖區(qū)訪問權(quán) !消費(fèi)者

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論