多線程實現生產者消費者(共15頁)_第1頁
多線程實現生產者消費者(共15頁)_第2頁
多線程實現生產者消費者(共15頁)_第3頁
多線程實現生產者消費者(共15頁)_第4頁
多線程實現生產者消費者(共15頁)_第5頁
已閱讀5頁,還剩15頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、嵌入式Linux編程課程設計題目(tm):多線程實現(shxin)生產者消費者之間的通信(tng xn)班 級: 計算機應用xxxx班 學 號: 12號 姓 名: xx 指導教師: xxx 日 期: 2014.6.232014.6.27 目 錄 TOC o 1-9 t 標題(biot) 1;1 h HYPERLINK l _Toc391617823 一、課程設計說明(shumng) PAGEREF _Toc391617823 h 1 HYPERLINK l _Toc391617824 二、概要(giyo)設計 PAGEREF _Toc391617824 h 1 HYPERLINK l _Toc

2、391617825 三、模塊設計 PAGEREF _Toc391617825 h 2 HYPERLINK l _Toc391617826 四、詳細設計 PAGEREF _Toc391617826 h 4 HYPERLINK l _Toc391617827 五、程序調試 PAGEREF _Toc391617827 h 6 HYPERLINK l _Toc391617828 六、總結 PAGEREF _Toc391617828 h 8 HYPERLINK l _Toc391617829 七、參考文獻 PAGEREF _Toc391617829 h 9 HYPERLINK l _Toc3916178

3、30 八、附錄 PAGEREF _Toc391617830 h 10一、課程設計說明(shumng)生產者-消費者(producer-consumer)問題,也稱作(chn zu)有界緩沖區(qū)(bounded-buffer)問題,兩個進程共享一個公共的固定大小的緩沖區(qū)。其中一個是生產者,用于將消息放入緩沖區(qū);另外一個是消費者,用于從緩沖區(qū)中取出消息。問題出現在當緩沖區(qū)已經滿了,而此時生產者還想向其中放入一個新的數據項的情形,其解決方法是讓生產者此時進行休眠,等待消費者從緩沖區(qū)中取走了一個或者多個數據后再去喚醒它。同樣地,當緩沖區(qū)已經空了,而消費者還想去取消息,此時也可以讓消費者進行休眠,等待生產

4、者放入一個或者多個數據時再喚醒它。本次課設通過研究Linux的進程機制和信號量實現(shxin)生產者消費者問題的并發(fā)控制。二、概要設計本作業(yè)是完善課件上的線程綜合實例的練習生產者-消費者問題,重構這個程序的框架,完成性能分析,使之進一步理解掌握Linux下線程的同步、通信以及互斥和多線程的安全問題。一般情況下,解決互斥方法常用信號量和互斥鎖,即semaphore和mutex,而解決這個問題,多采用一個類似資源槽的結構,每個槽位標示了指向資源的指針以及該槽位的狀態(tài),生產者和消費者互斥查詢資源槽,判斷是否有產品或者有空位可以生產,然后根據指針進行相應的操作。同時,為了告訴生產者或者消費者資源槽的

5、情況,還要有一個消息傳送機制,無論是管道還是線程通信。然而,本次試驗有幾個特殊的要求:1、循環(huán)緩沖。2、除了stderr,stdout等外,只用小于2個的互斥鎖、3、放棄資源槽分配機制,采用額外的數據結構。4、生產者一直持續(xù)生產,形成生產消費的良性循環(huán)。首先,使用一個互斥鎖,意味著資源槽機制就不能使用了。因為資源槽雖以用一個互斥鎖完成,但是需要有額外的通信,如果使用管道通信,則管道也必須是互斥,這就不滿足1個互斥鎖的要求。其次,要求生產者一直生產,這就否定了另外一種方法:消費者、生產者的位置均平等,消費者消費的時候生產者不能生產,生產者生產的時候消費者不能消費。因此,就需要采用A要求,也就是循

6、環(huán)鏈表的形式。為了保證互斥要求,需要定義一個數據結構,這個數據結構包含兩個指針,一個讀一個寫,同時(tngsh)有一個資源數目量,告訴生產者和消費者是否可以生產或者消費。由于該數據結構很小,因而可以對此結構互斥訪問。同時,對于每組數據,都有一個標志(biozh)位,表示此組數據是否被占用,生產者和消費者均可以先占用此位置然后完成相應的操作。當消費者互斥訪問此結構(jigu)時,首先判斷是否有數據可以取,如果沒有,直接等待,若有數據可取,先更改標志位占用此數據,并將資源數目-1。然后交出互斥,把數據拷貝到自己緩沖區(qū)內,清空數據。當生產者訪問時,首先判斷有沒有空位可以生產,如果沒有,直接等待,若有

7、數據可以生產,先判斷該位是否被占用,如果沒被占用,則占用此位置進行生產。生產完成后,將占用位改為未占用,同時將資源數目+1。三、模塊(m kui)設計采用信號量來解決n個進程的臨界區(qū)問題,這n個進程共享一個(y )信號量mutex(mutual exclusion),并初始化為1。利用p ,v原語操作結合信號量實現生產者和消費者進程對緩沖區(qū)的互斥訪問。3.1 生產者進程 if(fork() = 0 ) int i = 0; while( i 100) semop(emptyid , &P ,1 );semop(mutxid , &P , 1);array*(set)%MAXSEM = i +

8、1; printf(Producer %dn, array(*set)%MAXSEM); (*set)+; semop(mutxid , &V , 1); semop(fullid , &V , 1); i+; /end of while in line 62 sleep(10); printf(Producer is over); exit(0);圖 3-1 3.2 消費者進程/消費者A進程(jnchng) if(fork()=0) while(1) semop(fullid , &P , 1); semop(mutxid , &P , 1); if(*get = 100) break; *

9、sum+= array(*get)%MAXSEM;printf(The ComsumerA Get Number %dn, array(*get)%MAXSEM ); (*get)+; if( *get =100) printf(The sum is %d n , *sum); semop(mutxid , &V , 1); semop(emptyid , &V ,1 );圖 3-2 sleep(1); /end of while(1) in line 82 printf(ConsumerA is over); exit(0);/end of if in line 81else /消費者B進程

10、(jnchng) if(fork()=0) while(1) semop(fullid , &P , 1); semop(mutxid , &P , 1); if(*get = 100) break; *sum += array(*get)%MAXSEM; printf(The ComsumerB Get Number %dn, array(*get)%MAXSEM ); (*get)+; if( *get =100) printf(The sum is %d n , *sum); semop(mutxid , &V , 1); semop(emptyid , &V ,1 ); sleep(1

11、); /end of while(1) in line105 printf(ConsumerB is over); exit(0); /end of if in line 103 /end of else in line 101 四、詳細(xingx)設計主函數(hnsh)圖 4-1二、統計(tngj)線程圖 4-2三、生產者線程圖 4-3四、消費者線程圖 4-4五、程序調試5.1 調試(dio sh)記錄有三個warning:圖 5-1-1圖 5-1-2圖 5-1-35.2 運行(ynxng)結果圖 5-2-1圖5-2-2六、總結(zngji)在這次的課程設計中,我遇到(y do)了很大的困

12、難,對一些概念很不理解,不過通過和同學交流又上網查閱資料很好的解決了問題,讓我在這個過程中學到很多東西,也進一步理解操作系統的概念,同時對Linux編程也有了更多的學習。這個課程設計并不是(b shi)很完美,但是起碼能讓我們很好的理解了什么是生產者消費者問題。讓我對互斥問題有了更深的見解,同時也認識的到自己很大的不足,在以后的學習中會加以克服,增強自己的問題分析能力和動手實踐能力。雖然實驗以前我已經對信號量機制解決進程間同步問題的原理有了很清楚的認識,但是此次課程設計中仍然遇到了很多問題,如Linux系統下各種系統調用以及函數的各種參數,都花費了我很多時間去網上看各種資料雖然Linux系統中

13、可以很方便的閱讀源代碼以及使用man命令進行相應指令的查看,但是全英文的資料讓人看了不免有些發(fā)怵,看來還要多多加強計算機專業(yè)英語的學習,以后便可以在Linux系統中查看各種幫助文件。另一個問題就是在編譯的時候遇到(y do)的,剛開始用gcc o main main.c 進行編譯的時候總是(zn sh)提示出錯,后來查了相關資料才知道pthread 庫不是 Linux 系統默認的庫,連接時需要使用靜態(tài)庫 libpthread.a,所以在使用pthread_create()等函數時,需要鏈接該庫才能編譯通過。以前再用Windows IDE進行編程的時候基本上不會遇到這樣的問題,看來的確IDE為我

14、們(w men)做了很多工作,隱藏了一些技術細節(jié),有時候隱藏這些細節(jié)雖然可以方便我們,卻讓我們離真相越來越遠。最近使用Linux進行相關的編程操作,感悟還是挺多的。Windows下的層層封裝的確讓我們感到很方便,但同時也讓我們編程變得越來越不靈活。因為我們不用再去了解底層的東西因此一遇到問題就會束手無策。這段時間一直用Linux進行編程,感覺很方便,跟我以前想象地完全不一樣,而且我掌握了不少命令,比我以前用鼠標操作的時候快多了,而且在Bash下可以用Ctrl+Z隨時中止正在運行的進程或命令,再用fg %id 重新運行。Linux下的編程也很方便,我還了解了Makefile的編寫方法,在多文件編

15、程的時候可以極高地提高效率。 總之,我之后會加強專業(yè)英語的學習,以便更好的利用Linux操作系統進行編程之路的學習。七、參考文獻1Operating System Concepts(Sixth Edition)(操作系統概念)影印版 Abraham Silberschatz編 高等教育出版社 2003年2 操作系統 羅宇 鄒鵬 吳剛 等編著 電子工業(yè)出版社 2006年2計算機操作系統教程(第三版) 張堯學編 清華大學出版社 2001年3 計算機操作系統 第三版 湯曉丹 梁紅兵 哲鳳屛 湯子瀛 編著西安電子科技大學出版社 2009年4 操作系統(co zu x tn)原理(第三版) 龐麗萍 華中

16、科技大學出版社2000年八、附錄(fl)#include #include #include #include #include #include #include #include #define MAXSEM 5/聲明(shngmng)三個信號燈IDint fullid;int emptyid;int mutxid;int main() struct sembuf P,V; union semun arg; /聲明共享內存 int *array; int *sum; int *set; int *get; /映射共享內存array=(int*)mmap(NULL,sizeof( int )

17、*5,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0); sum=(int*)mmap(NULL, zeof( int ),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0); get=(int*)mmap(NULL,sizeof( int ),PROT_READ|PROT_WRITE,MAP_SHAR ED|MAP_ANONYMOUS,-1,0); set=(int*)mmap(NULL,sizeof( int ),PROT_READ|PROT_WRITE,MAP_SHAR ED|MAP

18、_ANONYMOUS,-1,0); *sum = 0; *get = 0; *set = 0; /生成信號燈 fullid= semget(IPC_PRIVATE,1,IPC_CREAT|00666); emptyid=semget(IPC_PRIVATE,1,IPC_CREAT|00666); mutxid=semget(IPC_PRIVATE,1,IPC_CREAT|00666); /為信號燈賦值 arg.val = 0; if(semctl(fullid , 0 , SETVAL , arg) = -1) perror(semctl setval error); arg.val = MA

19、XSEM; if(semctl(emptyid , 0 ,SETVAL , arg) = -1)perror(semctl setval error); arg.val = 1; if(semctl(mutxid , 0 ,SETVAL , arg) = -1) perror(setctl setval error); /初始化P,V操作(cozu) V.sem_num=0; V.sem_op =1; V.sem_flg=SEM_UNDO; P.sem_num=0; P.sem_op =-1; P.sem_flg=SEM_UNDO; /生產者進程(jnchng) if(fork() = 0 )

20、 int i = 0; while( i 100) semop( id , &P ,1 ); semop(mutxid , &P , 1); array*(set)%MAXSEM = i + 1; printf(Producer %dn, array(*set)%MAXSEM); (*set)+; semop(mutxid , &V , 1); semop(fullid , &V , 1); i+; sleep(10); printf(Producer is over); exit(0); else /消費者A進程(jnchng) if(fork()=0) while(1) semop(fullid , &P , 1); semop(mutxid , &P , 1); if(*get = 100) break; *sum += array(*get)%MAXSEM; printf(The Co

溫馨提示

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

評論

0/150

提交評論