操作系統(tǒng)課程設(shè)計生產(chǎn)者消費者_第1頁
已閱讀1頁,還剩13頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、<p> ?。ú僮飨到y(tǒng)課程設(shè)計)</p><p><b>  生</b></p><p><b>  產(chǎn)</b></p><p><b>  者</b></p><p><b>  和</b></p><p><b&

2、gt;  消</b></p><p><b>  費</b></p><p><b>  者</b></p><p>  學(xué)生姓名: </p><p>  學(xué)生學(xué)號: </p><p>  班 級: <

3、;/p><p><b>  課程題目分析</b></p><p>  這個題目是生產(chǎn)者向消費者提供商品,消費者消耗商品,并且兩組人共用同一緩沖區(qū)。生產(chǎn)者提供了商品之后消費者才能去取商品,消費者若不取走商品則當緩沖區(qū)用完之后生產(chǎn)者則不能再向緩沖區(qū)中添加新的商品。</p><p><b>  思考問題:</b></p>

4、<p>  對于生產(chǎn)者進程:每產(chǎn)生一個數(shù)據(jù),則需去訪問共用緩沖區(qū)是否有已滿,未滿則可以將該數(shù)據(jù)存入并通知消費者進程,否則不能。</p><p>  對于消費者進程:每當想去消費(取出數(shù)據(jù))時,則需訪問緩沖區(qū)是否為空,為空則不能消費(取出數(shù)據(jù)),否則可以取,并通知生產(chǎn)者。</p><p>  緩沖區(qū)是個臨界資源,所有的進程對于該空間都是共享的,所以,還有互斥問題存在。</

5、p><p><b>  課程設(shè)計目的</b></p><p>  通過實驗?zāi)M生產(chǎn)者與消費者之間的關(guān)系,了解并掌握他們之間的關(guān)系及原理。由此增加對進程同步問題的了解:</p><p>  掌握基本的同步互斥算法,理解生產(chǎn)者與消費者模型</p><p>  了解windows中多線程(多進程)的并發(fā)執(zhí)行機制,線程(進程)間的同

6、步于互斥</p><p>  學(xué)習(xí)使用windows中基本的同步對象,掌握相應(yīng)的API。</p><p><b>  課程設(shè)計內(nèi)容</b></p><p>  有n個生產(chǎn)者和m個消費者,連接在具有k個單位緩沖區(qū)的有界環(huán)轉(zhuǎn)緩沖上,故又稱有界緩沖問題。其中Pi和Cj都是并發(fā)進程,只要緩沖區(qū)未滿,生產(chǎn)者進程Pi所生產(chǎn)的產(chǎn)品就可投入緩沖區(qū);類似地,只要

7、緩沖區(qū)非空,消費者進程Cj就可以從緩沖區(qū)取走并消耗產(chǎn)品。</p><p><b>  開發(fā)環(huán)境</b></p><p>  操作系統(tǒng):Windows系統(tǒng)</p><p>  編寫語言:C++語言</p><p><b>  系統(tǒng)分析設(shè)計</b></p><p><b&g

8、t;  算法原理</b></p><p>  生產(chǎn)者——消費者問題是典型的進程同步問題,這些進程必須按照一定的生產(chǎn)率和消費率來訪問共享緩沖區(qū),用P、V操作解決生產(chǎn)者和消費者共享單緩沖區(qū)的問題,可設(shè)置兩個信號量empty和full,其初值分別為1和0,empty指示能否向緩沖區(qū)放入產(chǎn)品,full指示能否從緩沖區(qū)取出產(chǎn)品。為了使其協(xié)調(diào)工作,必須使用一個信號量mutex(初值為1),以限制生產(chǎn)者和消費者互斥

9、地對緩沖區(qū)進行存取,另用兩個信號量empty1(初值為緩沖區(qū)大?。┖蚮ull1(初值為0),以保證生產(chǎn)者不向已滿的緩沖區(qū)中放入產(chǎn)品,消費者不從空緩沖區(qū)中取產(chǎn)品。</p><p><b>  功能描述</b></p><p>  生產(chǎn)者功能描述:在同一個進程地址空間內(nèi)執(zhí)行兩個線程。生產(chǎn)者線程生產(chǎn)物品,然后將物品放置在一個空緩沖區(qū)中供消費者線程消費。當生產(chǎn)者線程生產(chǎn)物品時

10、,如果沒有空緩沖區(qū)可用,那么生產(chǎn)者線程必須等待消費者線程釋放出一個空緩沖區(qū)。</p><p>  消費者功能描述:消費者線程從緩沖區(qū)獲得物品,然后釋放緩沖區(qū),當消費者線程消費物品時,如果沒有滿的緩沖區(qū),那么消費者線程將被阻塞,直到新的物品被生產(chǎn)出來。</p><p><b>  算法流程圖</b></p><p>  生產(chǎn)者流程圖:

11、 消費者流程圖:</p><p><b>  總的流程圖:</b></p><p>  數(shù)據(jù)結(jié)構(gòu)及部分函數(shù)描述</p><p> ?。?)類SeqSquare:對類SeqSquare的聲明及其中一些函數(shù)</p><p>  class SeqSquare</p><p>

12、<b>  {</b></p><p><b>  public:</b></p><p>  SeqSquare(int n);</p><p>  ~SeqSquare();</p><p>  void P(int x);

13、 //p操作</p><p>  void V(int x); //v操作</p><p>  bool IsEmpty(); //判斷是否為空</p><p>  bool IsFull();

14、 //判斷是否已滿</p><p>  void deca();</p><p>  void decb();</p><p>  int getSize();</p><p>  int getmaxSize();</p><p>  int gettop();</p

15、><p>  int geta();</p><p>  int getb();</p><p>  protected:</p><p><b>  private:</b></p><p>  int *elements;</p><p>  int top,a,b,max

16、Size;</p><p><b>  };</b></p><p>  說明:①用動態(tài)整型數(shù)組*elements來代表緩沖區(qū),不管是生產(chǎn)產(chǎn)品還是對已有產(chǎn)品的消費都需要訪問該緩沖區(qū)。②函數(shù)IsFull()用于判斷緩沖區(qū)是否已滿,生產(chǎn)者能否使用緩沖區(qū)。③函數(shù)IsEmpty()用于判斷緩沖區(qū)是否為空,消費者能否使用緩沖區(qū)。</p><p>  生產(chǎn)

17、者和消費者操作及顯示函數(shù)showbuf:</p><p>  void producer(SeqSquare *a) //生產(chǎn)者操作</p><p><b>  {</b></p><p><b>  a->P(1);</b></p><p><b>  }&

18、lt;/b></p><p>  void consumer(SeqSquare *a) //消費者操作 </p><p><b>  {</b></p><p><b>  a->V(1);</b></p><p><b>  }</b>

19、;</p><p><b>  //緩沖區(qū)顯示</b></p><p>  void showbuf(SeqSquare *a)</p><p><b>  {</b></p><p>  int i=a->getSize();</p><p><b>  }

20、</b></p><p>  在實現(xiàn)本程序的生產(chǎn)者消費者模型時,具體地通過以下同步對象實現(xiàn)互斥:</p><p> ?、僭O(shè)一個互斥量Mutex,以實現(xiàn)生產(chǎn)者在查詢和保留緩沖區(qū)的下一個空位置時進行互斥。</p><p> ?、诿恳粋€生產(chǎn)者用一個信號量與消費者同步,通過設(shè)置Full實現(xiàn),該組信號量用于表示相應(yīng)產(chǎn)品以生產(chǎn)。同時用一個表示空緩沖區(qū)數(shù)目的信號量Em

21、pty進行類似的同步,指示緩沖區(qū)中是否存在空位置,以便開始生產(chǎn)下一個產(chǎn)品。</p><p><b>  調(diào)試過程</b></p><p>  為解決生產(chǎn)者、消費者問題,應(yīng)該設(shè)置兩個資源信號量,其中一個表示空緩沖區(qū)的數(shù)目,用Full表示,其初值為用戶輸入的緩沖區(qū)的大小,另一個表示緩沖區(qū)中產(chǎn)品的數(shù)目,用Empty表示,其初值為0.另外,由于緩沖區(qū)是一個臨界資源,必須互斥使

22、用,所以還需要再設(shè)置一個互斥信號量Mutex,其初值為1.</p><p>  在生產(chǎn)者、消費者問題中,信號量實現(xiàn)兩種功能。首先,他是生產(chǎn)產(chǎn)品和消費產(chǎn)品的計數(shù)器,計數(shù)器的初值是可使用的資源數(shù)目(緩沖區(qū)的長度)。其次,他是確保產(chǎn)品的生產(chǎn)者和消費者之間的動作同步的同步器。</p><p>  生產(chǎn)者要生產(chǎn)一個產(chǎn)品時,首先對資源信號量Full和互斥信號量Mutex進行P操作,申請資源。如果可以通

23、過的話,就生產(chǎn)一個產(chǎn)品,并把產(chǎn)品送人緩沖區(qū)。然后對互斥信號量Mutex和資源信號量Empty進行V操作,釋放資源。</p><p>  消費者要消費一個產(chǎn)品時,首先對資源信號量Empty和互斥信號量Mutex進行P操作,申請資源。如果可以通過的話就從緩沖區(qū)取出一個產(chǎn)品并消費掉。然后對互斥信號量Mutex和資源信號量Full進行V操作,釋放資源。</p><p>  如果緩沖區(qū)中已經(jīng)沒有可用

24、資源,就把申請資源的進程添加到等待隊列的隊尾。如果有一個資源被釋放,在等待隊列中的第一個進程被喚醒并取得這個資源的使用權(quán)。</p><p><b>  參考資料</b></p><p>  《操作系統(tǒng)教程》 孫鐘秀 高等教育出版社</p><p>  《C++程序設(shè)計》 譚浩強 高等教育出版社</p><p>&l

25、t;b>  運行實例及結(jié)果分析</b></p><p><b>  運行實例</b></p><p>  緩沖區(qū)大小為3,先生產(chǎn)一件產(chǎn)品,顯示緩沖區(qū),再接著生產(chǎn)一件產(chǎn)品,消耗一件產(chǎn)品,顯示緩沖區(qū),在消耗兩件產(chǎn)品,再生產(chǎn)4件產(chǎn)品,改變緩沖區(qū)的大小為6,顯示緩沖區(qū),選擇一個未出現(xiàn)的選項,退出程序。</p><p><b>

26、;  結(jié)果顯示</b></p><p><b>  結(jié)果分析</b></p><p>  在每個程序中需要先做P,后做V,二者要成對出現(xiàn),夾在二者中間的代碼段就是該進程的臨界區(qū)。</p><p>  對同步信號量full和empty的P,V操作同樣必須成對出現(xiàn),但它們分別位于不同的程序中。</p><p> 

27、?。?)無論在生產(chǎn)者進程中還是消費者進程中,兩個P操作的次序不能顛倒:應(yīng)先執(zhí)行同步信號量的P操作,然后執(zhí)行互斥信號量的P操作。否則可能造成進程死鎖。</p><p><b>  七、個人體驗</b></p><p>  雖然我也很想用java語言寫這個程序,但是由于自己學(xué)藝不精,所以只能用C++寫。通過這個實驗我發(fā)現(xiàn)我以前有很多知識都忘記了,重新拿起課本學(xué)習(xí)時發(fā)現(xiàn)原來

28、很多不懂得問題都有了新的認識,有一種豁然開朗的感覺。也為我考研開了一個好的開頭。</p><p>  我認為我完成的這個設(shè)計做的比較出色的地方是對C++語言中類以及數(shù)組的運用,其實這里我對數(shù)組的操作是按照“先進先出”的方法進行運作的,這是參考了棧的工作原理,因為緩沖區(qū)一般也是堆棧,比較符合設(shè)計要求。</p><p>  這次實驗中我感覺做的很粗糙,自己所想的模擬過程的確得到實現(xiàn)了,但是感覺

29、靈活性不太高,思考還不過全面,應(yīng)該以后多注意一下,多考慮考慮才是。</p><p>  在這次實驗中我重新將《C++程序設(shè)計》和《數(shù)據(jù)結(jié)構(gòu)》的幾個重要章節(jié)復(fù)習(xí)了一遍,對類、數(shù)組、C++的I/O流類庫以及堆棧的語句格式、注意細節(jié)都再一次熟悉,感覺蠻有趣的。不過,在編程過程中許多語句的小問題還真是出現(xiàn)不少,而且感覺自己對C++強大豐富的語句方法用得太呆板,不夠靈活,總是想到那些常用的,而忽略了顆粒讓語句更簡短的方法,

30、以后要多多注意才是。</p><p><b>  附錄</b></p><p>  // 生產(chǎn)者消費者1.cpp : Defines the entry point for the console application.</p><p><b>  //</b></p><p>  #includ

31、e "stdafx.h"</p><p>  #include "iostream"</p><p>  using namespace std;</p><p>  class SeqSquare</p><p><b>  {</b></p><p>&

32、lt;b>  public:</b></p><p>  SeqSquare(int n);</p><p>  ~SeqSquare();</p><p>  void P(int x); //p操作</p><p>  void V

33、(int x); //v操作</p><p>  bool IsEmpty(); //判斷是否為空</p><p>  bool IsFull();

34、 //判斷是否已滿</p><p>  void deca();</p><p>  void decb();</p><p>  int getSize();</p><p>  int getmaxSize();</p><p>  int gettop();</p><p

35、>  int geta();</p><p>  int getb();</p><p>  protected:</p><p><b>  private:</b></p><p>  int *elements;</p><p>  int top,a,b,maxSize;</p

36、><p><b>  };</b></p><p>  bool SeqSquare::IsEmpty() //判斷是否為空</p><p><b>  {</b></p><p>  return(top==-1)?tr

37、ue:false;</p><p><b>  }</b></p><p>  bool SeqSquare::IsFull() //判斷是否已滿</p><p><b>  {</b></p><p>  ret

38、urn(top>=maxSize-1)?true:false;</p><p><b>  }</b></p><p>  void SeqSquare::deca()</p><p><b>  {</b></p><p><b>  a--;</b></p>

39、;<p><b>  }</b></p><p>  void SeqSquare::decb()</p><p><b>  {</b></p><p><b>  b--;</b></p><p><b>  }</b></p>

40、;<p>  int SeqSquare::getSize()</p><p><b>  {</b></p><p>  return top+1;</p><p><b>  }</b></p><p>  int SeqSquare::getmaxSize()</p>

41、<p><b>  {</b></p><p>  return maxSize;</p><p><b>  }</b></p><p>  int SeqSquare::gettop()</p><p><b>  {</b></p><p

42、>  return top;</p><p><b>  }</b></p><p>  int SeqSquare::geta()</p><p><b>  {</b></p><p><b>  return a;</b></p><p>&

43、lt;b>  }</b></p><p>  int SeqSquare::getb()</p><p><b>  {</b></p><p><b>  return b;</b></p><p><b>  }</b></p><p&

44、gt;  SeqSquare::SeqSquare(int n)</p><p><b>  {</b></p><p><b>  top =-1;</b></p><p><b>  a = b =0;</b></p><p>  maxSize = n;</p>

45、;<p>  elements = new int[maxSize];</p><p><b>  }</b></p><p>  void SeqSquare::P(int x)</p><p><b>  {</b></p><p>  if(IsFull()==true)<

46、/p><p><b>  {</b></p><p><b>  a=a+1;</b></p><p><b>  }</b></p><p><b>  else</b></p><p><b>  {</b>&

47、lt;/p><p>  elements[++top] = x;</p><p><b>  }</b></p><p><b>  }</b></p><p>  void SeqSquare::V(int x)</p><p><b>  {</b>&l

48、t;/p><p>  if(IsEmpty()==true)</p><p><b>  {</b></p><p><b>  b = b+1;</b></p><p><b>  }</b></p><p><b>  else</b&g

49、t;</p><p><b>  {</b></p><p>  x = elements[top--];</p><p><b>  }</b></p><p><b>  }</b></p><p>  void producer(SeqSquare

50、 *a) //生產(chǎn)者操作</p><p><b>  {</b></p><p><b>  a->P(1);</b></p><p><b>  }</b></p><p>  void consumer(SeqSquare *a)

51、 //消費者操作 </p><p><b>  {</b></p><p><b>  a->V(1);</b></p><p><b>  }</b></p><p>  SeqSquare::~SeqSquare()</p><p&g

52、t;<b>  {</b></p><p>  delete elements; </p><p><b>  }</b></p><p><b>  //緩沖區(qū)顯示</b></p><p>  void showbuf(SeqSquare *a)</p><

53、;p><b>  {</b></p><p>  int i=a->getSize();</p><p><b>  }</b></p><p>  int main()</p><p><b>  {</b></p><p><b&g

54、t;  int i,n;</b></p><p>  cout<<"請輸入緩沖區(qū)大?。?quot;<<endl;</p><p><b>  cin>>n;</b></p><p>  SeqSquare *s;</p><p>  s = new SeqSqua

55、re(n);</p><p>  while(i!=4)</p><p><b>  {</b></p><p>  cout<<"請選擇操作: "<<endl;</p><p>  cout<<"1.生產(chǎn)一件產(chǎn)品;2.消

56、費一件產(chǎn)品"<<endl;</p><p>  cout<<"3.顯示緩沖區(qū); 4.退出系統(tǒng)。 "<<endl;</p><p>  cout<<"5.需要改變緩沖區(qū)大?。?"<<endl;</p><p><b>  cin&g

57、t;>i;</b></p><p><b>  switch(i)</b></p><p><b>  {</b></p><p><b>  case 1:</b></p><p>  producer(s);</p><p>  i

58、f (s->geta()==0)</p><p><b>  {</b></p><p>  cout<<endl<<"成功生產(chǎn)一件商品!"<<endl<<endl;</p><p><b>  }</b></p><p>&

59、lt;b>  else</b></p><p><b>  {</b></p><p>  cout<<endl<<"沒有空間供生產(chǎn)者生產(chǎn)!"<<endl<<endl;</p><p>  s->deca();</p><p>&

60、lt;b>  }</b></p><p><b>  break;</b></p><p><b>  case 2:</b></p><p>  consumer(s);</p><p>  if (s->getb()==0)</p><p><

61、;b>  {</b></p><p>  cout<<endl<<"成功消費一件商品!"<<endl<<endl;</p><p><b>  }</b></p><p><b>  else</b></p><p&g

62、t;<b>  {</b></p><p>  cout<<endl<<"沒有產(chǎn)品供消費者消費!"<<endl<<endl;</p><p><b>  }</b></p><p><b>  break;</b></p>

63、<p><b>  case 3:</b></p><p>  showbuf(s);</p><p>  cout<<endl<<"緩沖區(qū)已占用:"<<s->getSize()<<" "<<"可用空間為:"<<(

64、n-s->getSize())<<endl<<endl;</p><p><b>  break;</b></p><p><b>  case 4:</b></p><p>  cout<<endl<<"成功退出程序!"<<endl&l

65、t;<endl;</p><p><b>  break;</b></p><p><b>  case 5:</b></p><p>  cout<<endl<<"請輸入緩沖區(qū)大小:"<<endl;</p><p><b> 

66、 cin>>n;</b></p><p>  s = new SeqSquare(n);</p><p>  cout<<endl<<"緩沖區(qū)大小已發(fā)生改變,數(shù)據(jù)已清除!"<<endl<<endl;</p><p><b>  break;</b><

67、;/p><p><b>  default:</b></p><p>  cout<<endl<<"輸入操作不正確,請重新輸入!"<<endl<<endl;</p><p><b>  }</b></p><p><b>  

溫馨提示

  • 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論