生產者-消費者問題_第1頁
生產者-消費者問題_第2頁
生產者-消費者問題_第3頁
生產者-消費者問題_第4頁
生產者-消費者問題_第5頁
已閱讀5頁,還剩4頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

暨燧工等院

課程設計報告

課程名:操作系統

專業__________________________________

學生姓名__________________________________

班級__________________________________

學號__________________________________

指導教師__________________________________

完成日期__________________________________

博雅學院

“操作系統”課程設計報告

-生產者?消費者問題的模擬實現

1.課程設計的目的

本課程設計是學習完“操作系統原理”課程后進行的一次全面的綜合訓練,通

過課程設計,更好地掌握操作系統的原理及實現方法,加深對操作系統基礎理論和

重要算法的理解,加強學生的動手能力。

2.設計內容

2.1概述

用多進程同步方法解決生產者■消費者問題,C或C++語言實現。

通過研究Linux的進程機制和信號量實現生產者消費者問題的并發控制。

說明:有界緩沖區內設有20個存儲單元,放入/取出的數據項設定為1-20這20個

整型數。

設計要求:⑴每個生產者和消費者對有界緩沖區進行操作后,即時顯示有界緩沖

區的全部內容,當前指針位置和生產者/消費者縣城的標識符。(2)生產者和消費者各

有兩個以上。(3)多個生產者或多個消費者之間須有共享對緩沖區進行操作的函數代

碼。

2.2設計原理

多進程是一種非常簡潔的多任務操作方式。在Linux系統下,啟動一個新的進

程必須分配給它獨立的地址空間,建立眾多的數據表來維護它的代碼段、堆棧段和

數據段,這是一種煩瑣的多任務工作方式。

生產者■消費者方案是多進程應用程序開發中最常用的構造之一。因此困難也在

于此。因為在一個應用程序中可以多次重復生產者-消費者行為,其代碼也可以如此。

設計中創建了Consumer類,該類通過在一些多進程應用程序中促進代碼重用以及

簡化代碼調試和維護來解決這個問題。多進程應用程序通常利用生產者■消費者編程

方案,其中由生產者進程創建重復性作業,將其傳遞給作業隊列,然后由消費者進

程處理作業。

多進程是一種使應用程序能同時處理多個操作的編程技術。通常有兩種不同類

型的多進程操作使用多個進程:適時事件,當作業必須在特定的時間或在特定的間

隔內調度執行時;后臺處理,當后臺事件必須與當前執行流并行處理或執行時;適

時事件的示例包括程序提醒、超時事件以及諸如輪詢和刷新之類的重復性操作。后

臺處理的示例包括等待發送的包或等待處理的已接收的消息。

生產者-消費者方案很適合于后臺處理類別的情況。這些情況通常圍繞一個作業

“生產者”方和一個作業“消費者”方。當然,關于作業并行執行還有其它考慮事

項。在大多數情況下,對于使用同一資源的作'也,應以FCFS的方式按順序處理,這

可以通過使用單進程的消費者輕松實現。通過使用這種方法,使用單個進程來訪問

單個資源,而不是用多個進程來訪問單個資源。要啟用標準消費者,當作業到來時

創建一個作業隊列來存儲所有作業。生產者進程通過將新對象添加到消費者隊列來

交付這個要處理的新對象。然后消費者進程從隊列取出每個對象,并依次處理。當

隊列為空時,消費者進入休眠。當新的對象添加到空隊列時,消費者會醒來并處理

該對象。

2.3詳細設計及編碼

(1)調試問題分析

為解決生產者/消費者問題,應該設置兩個資源信號量,其中一個表示空緩沖區

的數目,用Full表示,其初始值為有界緩沖區的大小BUFFER_NUM;另一個表示

緩沖區中產品的數目,用Empty表示,其初始值為()。另外,由于有界緩沖區是一

個臨界資源,必須互斥使月,所以還需要再設置一個互斥信號量Mutex,起初值為1。

在生產者/消費者問題中,信號量實現兩種功能。首先,它是生產產品和消費產

品的計數器,計數器的初始值是可利用的資源數目(有界緩沖區的長度)。其次,它是

確保產品的生產者和消費者之間動作同步的同步器。

生產者要生產一個產品時,首先對資源信號量Full和互斥信號量Mutex進行P

操作,申請資源。如果可以通過的話,就生產一個產品,并把產品送入緩沖區。然

后對互斥信號量Mutex和資源信號量Empty進行V操作,釋放資源。

消費者要消費一個產品時,首先對資源信號量Empty和互斥信號量Mutex進行

P操作,申請資源。如果可以通過的話,就從緩沖區取出一個產品并消費掉。然后

對互斥信號量Mutex和資源信號量Full進行V操作,釋放資源。

如果緩沖區中已經沒有可用資源,就把申請資源的進程添加到等待隊列的隊尾。

婦果有一個資源被釋放,在等待隊列中的第一個進程被喚醒并取得這個資源的使用

權。

圖2-2消費者流程圖

(3)源程序

#include<windows.h>

#include<stdio.h>

#include<stdlib.h>

#include<time.h>

typedefHANDLESemaphore;//信號量的Windows原型

升defineP(S)WaitForSingleObject(SJNFINITE)//定義Windows下的P操作

#defineV(S)ReleaseSemaphore(S,1,NULL)//定義Windows下的V操作

#definerate100()

#defineCONSUMER_NUM2/*消費者個數*/

#definePRODUCER_NUM3/*生產者個數*/

#defineBUFFER_NUM20/*緩沖區個數*/

char*thing[8]={〃豆漿〃,〃油條〃,〃燒餅〃,〃牛奶〃,〃包子“,〃燒賣",〃煎蛋〃,〃雪碧

“};〃生產和消費的產品名稱

structBuffer

(

intproduct[BUFFER_NUM];//緩沖區

intstart,end;//兩個指針相當于教材中的inout指針

Jg.buf;

SemaphoreEmpty,FulkMutex;//分另U相當于Empty,FulkMutex三個信號量

<

DWORDWINAP1Consumer(LPVOIDpara)

f

t

//i表示第i個消費者

inti=*(int*)para;〃利用para傳入當前消費者的編號

intptr;//待消費的內容的指針

printf(〃消費者%Id:需要資源\n〃,i);

intj=0;

while(j++<4){

//等待產品

P(Full):

//有產品,先鎖住緩沖區

P(Mutcx);

//記錄消費的物品

ptr=g_buf.start;

//再移動緩沖區指針

g_buf.slail-(g_buf.blarl+l)%BUFFER_NUM,

〃讓其他消費者或生產者使用

printf(z,消費者%01d:SH?buf[%d]=%s\n,,,i,ptr,thing[g_duct[ptr]]);

〃消費完畢,并釋放一個緩沖

printf(,z消費者%01d:我消費完畢%s\n”,ijhing[g_duct[ptr]]);

V(Mutex);

V(Empty);

S1eep(rate*rand()%10+110);

)

return0;

}

/'不不不不不不不不不不不不不不不sL*不/f-/.y"-〃t:力+不I小不不不不不不不不不不不不不不不不不不不不不不不不不?X?不?2x不不不不/

DWORDWINAP1Producer(LPVOIDpara)

(

inti=*(int*)para-CONSUMERNUM;

intptr;

intdata;〃產品

intj=0;

while(j++<4)

{

data=rand()%8;

prinlf("生產者%Old:生產出:%s!Xn^,i,(hing[dataj);

〃等待存放空間

P(Empty);

〃有地方,先鎖住緩沖區

P(Mutex);

〃記錄消費的物品

ptr=g_buf.end;

〃再移動緩沖區指針

g_buf.end=(g_buf.end+1)%BUFFER_NUM;

printf("生產者%Old:放到緩沖區buf[%d]=%s\n*,i,ptr,thing[data]);

g_duct[ptrj=data;

〃放好了完畢,釋放一個產品

〃讓其他消費者或生產者使用

V(Mutex);

V(Full);

Sleep(rate/2*rand()%10+l10);

)

return0;

intmain(intargc,char*argv[])

(

〃線程技術,前面為消費者線程,后面為生產者線程

HANDLEhThread[CONSUMER_NUM+PRODUCER_NUM];//線程計

srand(time(NULL));

rand();

DWORDtid;

inti=0;

〃初始化信號量

Mutex=CreateSemapliore(NULL,1,1,"MutexOfConsumerAndProducer");

Empty=CreateSemaphore(NULL,BUFFER_NUM,BUFFER.NUM,

"BuffcrScmaphone");

Full=CreateSemaphore(NULL,0,BUFFER_NUM,"ProductSemaphone");

if(!Empty||!Full||!Mutcx)

(

printf("CrcatcScmaphoncError!\n");

return-1;

)

inttotalThreads=CONSUMER_NUM+PRODUCER_NUM;

〃開啟消費者線程

printf(〃先請消費者上席!\n〃);

for(i=0;i<CONSUMER_NUM;i++)

(

hThread[i]=CreateThread(NULL,0,Consumer,&i,O,&tid);

if(hThread[i])WaitForSingleObject(hThread[i]J0);

)

printf("生產者就位!\nM);

for(;i<totalThreads;i++)

(

hThread[i]=CreateThread(NULL,(),Producer,&i,0,&lid);

if(hThread(i])WaitForSingleObject(hThread[i],10);

)

〃生產者和消費者的執行

WaitForMukipleObjects(tolalThreads,hThread,TRUEJNFINITE);

return0;

3結果及分析

"C:\Progra>Files\HicrosoftVisualStudio\?yProjects\楊慧\Debug\楊慧.exe-l°h[

與常

翼要

者S1

費;

而要

整fJ

產y

繇bu[0]=

[=r漿

甲01s

wK衣

產IC

1嘮

馨1]

m賣

7荀

蜴?

產B

^生?

?

產W

糊?

尸.▼

t者0f?

I

費2]

我>J

¥者0tm

..邨f

.]=

費者

[3碧

生bu

需5,▼

bu肖

1:生

生??e

?完

i一

.G

c("C:\PrograMFilesMicrosoftVisualStudioUyProjects\楊急\Debug\楊款.exe-h|x|

生產者U消費者雪碧?

比魄者U魏逐完畢油.□

生產者[二放到的童bu£[4]=雪碧

生產者2:生產在燒餅?

生_產.者-2:放到期區buF[51=燒餅

消費者0:莪需要bu£[4]=雪碧

用費者。:璘卷竽雪碧

生產者0:生產苗:賽餅?

生產者0:放到研區bu£[6]=燒餅

消費者1:糙要buF[5]=施打

上肖費者工:在

生產者U.生產出:的油條條?;

.我消麟畢燒餅

消費者1:執以曰更!)

生產譽,放到緩沖囪油條

生產者2:生產田:燒賣?

生產者2:放到緩沖區buF[8]=燒賣

生產京豆漿?

生產者0:

生產者。:生產出:豆漿?

uf[6]=

酒費者。:一攜密元軍烷餅_入

生產者0:放到的短buf[9J=豆漿

生產者1:生產出:牛

生產者1:生產出:牛

逍囂耋,:費甯器處於“?由條

理者工:我置卷完畢油條

生產者「放到現能

buf[

溫馨提示

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

評論

0/150

提交評論