消費者生產者問題計算機操作系統(tǒng)課程設計_第1頁
消費者生產者問題計算機操作系統(tǒng)課程設計_第2頁
消費者生產者問題計算機操作系統(tǒng)課程設計_第3頁
消費者生產者問題計算機操作系統(tǒng)課程設計_第4頁
消費者生產者問題計算機操作系統(tǒng)課程設計_第5頁
已閱讀5頁,還剩11頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、齊齊哈爾大學操作系統(tǒng)課程綜合實踐題目:多進程同步方法解決生產者消費者問題班級:0姓名:0 學號:0指導教師:0 2011年12 月7日綜合實踐評分表班級0姓名0指導教師0題目:多進程同步方法解決生產者消費者問題 評分標準評分標準分數權重評分的依據得分AC選題10選題符合大綱要求,題目較新穎,工作量大選題基本符合大綱要求,工作量適中工作態(tài)度10態(tài)度端正,能主動認真完成各個環(huán)節(jié)的工作,不遲到早退,出勤好。能夠完成各環(huán)節(jié)基本工作,出勤較好。存儲結構、算法描述20能正確選擇存儲結構,定義準確,算法流程圖或類C語言描述的算法準確無誤能正確選擇存儲結構,算法流程圖或類C語言描述的算法基本準確獨立解決問題的

2、能力10具有獨立分析、解決問題能力,有一定的創(chuàng)造性,能夠獨立完成軟件的設計與調試工作,程序結構清晰,邏輯嚴謹,功能完善。有一定的分析、解決問題能力。能夠在老師指導下完成軟件的設計與調試工作,程序功能較完善。答辨問題回答20能準確回答老師提出的問題能基本準確回答老師提出的問題程序運行情況10程序運行正確、界面清晰,測試數據設計合理。程序運行正確、界面較清晰,能給出合適的測試數據。綜合實踐報告20格式規(guī)范,層次清晰,設計思想明確,解決問題方法合理,體會深刻。格式較規(guī)范,設計思想基本明確,解決問題方法較合理。總分指導教師(簽字): 注:介于A和C之間為B級,低于C為D級和E級。按各項指標打分后,總分

3、在90100為優(yōu),8089為良,7079為中,6069為及格,60分以下為不及格。多進程同步方法解決生產者消費者問題摘要:本文論述了多進程同步方法解決生產者消費者問題的過程。該程序使學生對操作系統(tǒng)的工作機制有了初步的了解,其主要目的是使學生了解和撐握在Linux系統(tǒng)平臺下的C語言編程,用來解決實現生活中遇到的問題。并以Linux系統(tǒng)開發(fā)平臺,以及虛擬機來實現。關鍵字:生產者消費者問題,Linux系統(tǒng)平臺,虛擬機,信號量,線程(thread)多進程同步方法解決生產者消費者問題一、課程設計所需設備計算機一臺,Red Hat linux9.03系統(tǒng)一套。二、課程設計預期目的通過研究Linux 的進程

4、機制和信號量實現生產者消費者問題的并發(fā)控制。三、課程設計任務用多進程同步方法解決生產者-消費者問題設計目的:通過研究Linux 的進程機制和信號量實現生產者消費者問題的并發(fā)控制.說明:有界緩沖區(qū)內設有20個存儲單元,放入/取出的數據項設定為1-20這20個整型數.設計要求:1) 每個生產者和消費者對有界緩沖區(qū)進行操作后,即時顯示有界緩沖區(qū)的全部內容,當前指針位置和生產者/消費者線程的標識符.2) 生產者和消費者各有兩個以上.3) 多個生產者或多個消費者之間須有共享對緩沖區(qū)進行操作的函數代碼.四、課程設計基本思想多進程是一種非常簡潔的多任務操作方式。在Linux系統(tǒng)下,啟動一個新的進程必須分配給

5、它獨立的地址空間,建立眾多的數據表來維護它的代碼段、堆棧段和數據段,這是一種煩瑣的多任務工作方式。生產者-消費者方案是多進程應用程序開發(fā)中最常用的構造之一。因此困難也在于此。因為在一個應用程序中可以多次重復生產者-消費者行為,其代碼也可以如此。設計中創(chuàng)建了 Consumer 類,該類通過在一些多進程應用程序中促進代碼重用以及簡化代碼調試和維護來解決這個問題。多進程應用程序通常利用生產者-消費者編程方案,其中由生產者進程創(chuàng)建重復性作業(yè),將其傳遞給作業(yè)隊列,然后由消費者進程處理作業(yè)。多進程是一種使應用程序能同時處理多個操作的編程技術。通常有兩種不同類型的多進程操作使用多個進程:適時事件,當作業(yè)必須

6、在特定的時間或在特定的間隔內調度執(zhí)行時;后臺處理,當后臺事件必須與當前執(zhí)行流并行處理或執(zhí)行時;適時事件的示例包括程序提醒、超時事件以及諸如輪詢和刷新之類的重復性操作。后臺處理的示例包括等待發(fā)送的包或等待處理的已接收的消息。生產者-消費者方案很適合于后臺處理類別的情況。這些情況通常圍繞一個作業(yè)“生產者”方和一個作業(yè)“消費者”方。當然,關于作業(yè)并行執(zhí)行還有其它考慮事項。在大多數情況下,對于使用同一資源的作業(yè),應以FCFS的方式按順序處理,這可以通過使用單進程的消費者輕松實現。通過使用這種方法,使用單個進程來訪問單個資源,而不是用多個進程來訪問單個資源。要啟用標準消費者,當作業(yè)到來時創(chuàng)建一個作業(yè)隊列

7、來存儲所有作業(yè)。生產者進程通過將新對象添加到消費者隊列來交付這個要處理的新對象。然后消費者進程從隊列取出每個對象,并依次處理。當隊列為空時,消費者進入休眠。當新的對象添加到空隊列時,消費者會醒來并處理該對象。五詳細設計5.1、調試問題分析為解決生產者/消費者問題,應該設置兩個資源信號量,其中一個表示空緩沖區(qū)的數目,用Full表示,其初始值為有界緩沖區(qū)的大小BUFFER_NUM;另一個表示緩沖區(qū)中產品的數目,用Empty表示,其初始值為0。另外,由于有界緩沖區(qū)是一個臨界資源,必須互斥使用,所以還需要再設置一個互斥信號量Mutex,起初值為1。 在生產者/消費者問題中,信號量實現兩種功能。首先,它

8、是生產產品和消費產品的計數器,計數器的初始值是可利用的資源數目(有界緩沖區(qū)的長度)。其次,它是確保產品的生產者和消費者之間動作同步的同步器。 生產者要生產一個產品時,首先對資源信號量Full和互斥信號量Mutex進行P操作,申請資源。如果可以通過的話,就生產一個產品,并把產品送入緩沖區(qū)。然后對互斥信號量Mutex和資源信號量Empty進行V操作,釋放資源。 消費者要消費一個產品時,首先對資源信號量Empty和互斥信號量Mutex進行P操作,申請資源。如果可以通過的話,就從緩沖區(qū)取出一個產品并消費掉。然后對互斥信號量Mutex和資源信號量Full進行V操作,釋放資源。如果緩沖區(qū)中已經沒有可用資源

9、,就把申請資源的進程添加到等待隊列的隊尾。如果有一個資源被釋放,在等待隊列中的第一個進程被喚醒并取得這個資源的使用權。 5.2、程序流程圖生產者線程開始資源信號量P操作互斥信號量P操作生產一個產品把產品送入緩沖區(qū)互斥信號量V操作資源信號量V操作等待隊列中有消費者線程等待隊列中有消費者線程線程自我阻塞添加到等待隊列線程自我阻塞添加到等待隊列未通過未通過通過通過喚醒對頭的消費者線程喚醒對頭的消費者線程生產者線程結束YYNN圖一 生產者流程結構消費者線程開始資源信號量P操作互斥信號量P操作從緩沖區(qū)取出一個產品消費一個產品互斥信號量V操作資源信號量V操作等待隊列中有生產者線程等待隊列中有生產者線程線程

10、自我阻塞添加到等待隊列線程自我阻塞添加到等待隊列未通過未通過通過通過喚醒對頭的生產者線程喚醒對頭的生產者線程消費者線程結束YYNN圖二 消費者流程結構5.3、程序自定義函數1、void produce(struct sem_info * );這個函數是生產者進行的生產過程,為所有的生產者所共享。結構體指針用來接收生產者線程創(chuàng)建時傳來的生產者的個人信息。2、void consumer(struct sem_info * );這個函數是消費者進行的生產過程,為所有的消費者所共享。結構體指針用來接收消費者線程創(chuàng)建時傳來的消費者的個人信息。3、void setproduce(void); 這個函數是用

11、來設置生產者的個數和他們的名字。4、void setconsumer(void);這個函數是用來設置消費者的個數和他們的名字。5、void activepthread(int);這個函數是用來創(chuàng)建生產者線程,int型參數為生產者的個數。6、void activecthread(int);這個函數是用來創(chuàng)建生產者線程,int型參數為生產者的個數。7、int gettime(void);這個函數返回來一個整數,作為線程的sleep()函數的參數。8、void myscanf(void);這個函數用來獲取設置生產者和消費者的個數時的整數,確保這個數字在0到MAX_BUFFER之間。5.4、系統(tǒng)函數調

12、用線程Linux系統(tǒng)下的多線程遵循POSIX線程接口,稱為pthread。編寫Linux下的多線程程序,需要使用頭文件pthread.h,連接時需要使用庫libpthread.a。Linux下pthread的實現是通過系統(tǒng)調用clone()來實現的。clone()是Linux所特有的系統(tǒng)調用,它的使用方式類似fork。函數pthread_create用來創(chuàng)建一個線程,它的原型為:extern int pthread_create _P (pthread_t *_thread, _const pthread_attr_t *_attr,void *(*_start_routine) (void

13、*), void *_arg);第一個參數為指向線程標識符的指針,第二個參數用來設置線程屬性,第三個參數是線程運行函數的起始地址,最后一個參數是運行函數的參數。第二個參數我們也設為空指針,這樣將生成默認屬性的線程。當創(chuàng)建線程成功時,函數返回0,若不為0則說明創(chuàng)建線程失敗,常見的錯誤返回代碼為EAGAIN和EINVAL。前者表示系統(tǒng)限制創(chuàng)建新的線程,例如線程數目過多了;后者表示第二個參數代表的線程屬性值非法。創(chuàng)建線程成功后,新創(chuàng)建的線程則運行參數三和參數四確定的函數,原來的線程則繼續(xù)運行下一行代碼。函數pthread_join用來等待一個線程的結束。函數原型為:extern int pthrea

14、d_join _P (pthread_t _th, void *_thread_return);第一個參數為被等待的線程標識符,第二個參數為一個用戶定義的指針,它可以用來存儲被等待線程的返回值。這個函數是一個線程阻塞的函數,調用它的函數將一直等待到被等待的線程結束為止,當函數返回時,被等待線程的資源被收回。一個線程的結束有兩種途徑,一種是函數結束了,調用它的線程也就結束了;另一種方式是通過函數pthread_exit來實現。它的函數原型為:extern void pthread_exit _P (void *_retval) _attribute_ (_noreturn_);唯一的參數是函數的

15、返回代碼,只要pthread_join中的第二個參數thread_return不是NULL,這個值將被傳遞給 thread_return。最后要說明的是,一個線程不能被多個線程等待,否則第一個接收到信號的線程成功返回,其余調用pthread_join的線程則返回錯誤代碼ESRCH。信號量信號量本質上是一個非負的整數計數器,它被用來控制對公共資源的訪問。當公共資源增加時,調用函數sem_post()增加信號量。只有當信號量值大于時,才能使用公共資源,使用后,函數sem_wait()減少信號量。函數sem_trywait()和函數pthread_ mutex_trylock()起同樣的作用,它是函

16、數sem_wait()的非阻塞版本。它們都在頭文件 /usr/include/semaphore.h中定義。信號量的數據類型為結構sem_t,它本質上是一個長整型的數。函數sem_init()用來初始化一個信號量。它的原型為:extern int sem_init _P (sem_t *_sem, int _pshared, unsigned int _value);sem為指向信號量結構的一個指針;pshared不為時此信號量在進程間共享,否則只能為當前進程的所有線程共享;value給出了信號量的初始值。函數sem_post( sem_t *sem )用來增加信號量的值。當有線程阻塞在這個信

17、號量上時,調用這個函數會使其中的一個線程不在阻塞,選擇機制同樣是由線程的調度策略決定的。函數sem_wait( sem_t *sem )被用來阻塞當前線程直到信號量sem的值大于0,解除阻塞后將sem的值減一,表明公共資源經使用后減少。函數sem_trywait ( sem_t *sem )是函數sem_wait()的非阻塞版本,它直接將信號量sem的值減一。函數sem_destroy(sem_t *sem)用來釋放信號量sem。六源程序清單6.1、源程序#include <windows.h> #include <stdio.h> #include <stdli

18、b.h> #include <time.h> typedef HANDLE Semaphore; / 信號量的Windows原型 #define P(S) WaitForSingleObject(S,INFINITE) / 定義Windows下的P操作 #define V(S) ReleaseSemaphore(S,1,NULL) / 定義Windows下的V操作 #define rate 1000 #define CONSUMER_NUM 2 /* 消費者個數 */ #define PRODUCER_NUM 3 /* 生產者個數 */ #define BUFFER_NUM

19、20 /* 緩沖區(qū)個數 */ char *thing8 = "雞腿堡", "薯條", "可樂", "三明治", "面包", "小籠包", "火腿","饅頭" /生產和消費的產品名稱 struct Buffer int productBUFFER_NUM; / 緩沖區(qū) int start,end; / 兩個指針相當于教材中的 in out 指針 g_buf; Semaphore Empty,Full,Mutex; /分別相當于Empty,

20、 Full, Mutex三個信號量 /* 消費者線程*/ DWORD WINAPI Consumer(LPVOID para) / i表示第i個消費者 int i = *(int *)para; /利用para傳入當前消費者的編號 int ptr; / 待消費的內容的指針 printf("消費者%1d: 需要資源n", i); int j=0; while (j+<4) / 等待產品 P(Full); / 有產品,先鎖住緩沖區(qū) P(Mutex); / 記錄消費的物品 ptr=g_buf.start; / 再移動緩沖區(qū)指針 g_buf.start= (g_buf.sta

21、rt+1)%BUFFER_NUM; /讓其他消費者或生產者使用 printf(" 消費者%01d: 我需要buf%d=%sn",i, ptr, thingg_ductptr); /消費完畢,并釋放一個緩沖 printf(" 消費者%01d: 我消費完畢%sn", i,thingg_ductptr); V(Mutex); V(Empty); Sleep(rate*rand()%10+110); return 0; /* 生產者線程*/ DWORD WINAPI Producer(LPVOID para) int i = *(in

22、t *)para - CONSUMER_NUM; int ptr; int data; /產品 int j=0; while(j+<4) data=rand()%8; printf("生產者%01d: 生產出: %s!n",i,thingdata); /等待存放空間 P(Empty); /有地方,先鎖住緩沖區(qū) P(Mutex); /記錄消費的物品 ptr=g_buf.end; /再移動緩沖區(qū)指針 g_buf.end =(g_buf.end+1)%BUFFER_NUM; printf("生產者%01d: 放到緩沖區(qū) buf%d=%sn",i,ptr,

23、thingdata); g_ductptr=data; /放好了完畢,釋放一個產品 /讓其他消費者或生產者使用 V(Mutex); V(Full); Sleep(rate/2*rand()%10+110); return 0; int main(int argc,char *argv) /線程技術,前面為消費者線程,后面為生產者線程 HANDLE hThreadCONSUMER_NUM+PRODUCER_NUM; / 線程計數 srand(time(NULL); rand(); DWORD tid; int i=0; /初始化信號量 Mutex=CreateSemaphore(N

24、ULL,1,1,"MutexOfConsumerAndProducer"); Empty=CreateSemaphore(NULL, BUFFER_NUM, BUFFER_NUM, "BufferSemaphone"); Full=CreateSemaphore(NULL,0,BUFFER_NUM,"ProductSemaphone"); if(!Empty|!Full|!Mutex) printf("Create Semaphone Error!n"); return -1; int totalThreads=C

25、ONSUMER_NUM+PRODUCER_NUM; /開啟消費者線程 printf("先請消費者上席!n"); for(i=0;i<CONSUMER_NUM; i+) hThreadi=CreateThread(NULL, 0, Consumer, &i,0,&tid); if(hThreadi)WaitForSingleObject(hThreadi,10); printf("生產者就位!n"); for(;i<totalThreads;i+) hThreadi=CreateThread(NULL,0,Producer,&i,0,&tid); if(hThreadi)WaitForSingleObject(hThreadi,10); /生產者和消費者的執(zhí)行 WaitForMultipleObjects(totalThreads,hThread,TRUE,INFINITE); return 0; 6.2、編譯及運行結果在程序中設置了兩個消費者,三個生產者,為便于描述出生產-消費的

溫馨提示

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

評論

0/150

提交評論