讀者寫者問題-操作系統(tǒng)實驗報告_第1頁
讀者寫者問題-操作系統(tǒng)實驗報告_第2頁
讀者寫者問題-操作系統(tǒng)實驗報告_第3頁
讀者寫者問題-操作系統(tǒng)實驗報告_第4頁
讀者寫者問題-操作系統(tǒng)實驗報告_第5頁
已閱讀5頁,還剩9頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、實驗內(nèi)容 1、定義一個數(shù)據(jù)緩存buffer及用于實現(xiàn)同步互斥的信號量。 2、定義一個讀者函數(shù):l 當(dāng)有寫者在占用buffer時,讀者應(yīng)該等待,直到寫者不再使用該buffer。l 當(dāng)有其他讀者在占用buffer時,讀者可對buffer進行讀取操作。l 當(dāng)buffer中有數(shù)據(jù)時,則從其中讀取一個數(shù)據(jù),并顯示然后退出。l 當(dāng)buffer中沒有數(shù)據(jù)時,應(yīng)等待,直到buffer中有數(shù)據(jù)可讀。 3、定義一個寫者函數(shù)l 當(dāng)有讀者在占用buffer時,寫者應(yīng)該等待,直到所有的讀者都退出為止。l 當(dāng)有其他寫者占用buffer時,該寫者應(yīng)該等待,直到占用buffer的寫者退出為止。l 當(dāng)buffer有空閑時,寫者

2、應(yīng)該在buffer中寫入一個數(shù)據(jù)并退出。l 當(dāng)buffer滿時,寫者應(yīng)該等待,直到buffer有空閑為止。 4、定義主函數(shù),在其中可以任意創(chuàng)建讀者與寫者。l 可根據(jù)用戶輸入創(chuàng)建讀者或?qū)懻哌M程(線程)。 5、用戶界面2. 寫者:開始讀出的內(nèi)容:1. 讀者:開始結(jié)束21讀者隊列等待結(jié)束寫出的內(nèi)容:Hello world !結(jié)束實驗當(dāng)堂所要完成事情列表:1. 調(diào)試程序使其在讀者優(yōu)先模式下可以運行并且能實現(xiàn)基本的功能得出正確的結(jié)果:能夠?qū)崿F(xiàn)讀寫互斥,寫寫互斥,讀讀不互斥,一個進程結(jié)束能夠喚醒等待隊列中的進程(先讀者隊列后寫著隊列)2. 根據(jù)實驗要求完善功能:由用戶決定寫者向緩沖區(qū)中寫入的內(nèi)容,讀者能夠

3、讀出并顯示出來;當(dāng)緩沖區(qū)中沒有數(shù)據(jù)時,讀者要等待,直到緩沖區(qū)中有數(shù)據(jù)才能讀3. 根據(jù)“讀者優(yōu)先”加以改變,增加一個“寫者優(yōu)先”模式,并且由用戶來選擇模式源代碼:#include<stdio.h>#include<stdlib.h>int rcount=0;/正在讀的讀者數(shù)量int wcount=0;/寫者隊列中等待寫操作的寫者數(shù)量int read_id=0;/讀進程號int write_id=0;/寫進程號int w=1;/讀寫互斥信號量char temp300 = '0'int choice; /用戶選擇讀者優(yōu)先OR寫者優(yōu)先int sign; /標(biāo)識t

4、emp空的信號量 0表示temp空void WFwakeup();void RFwakeup();struct rqueue/讀者等待隊列int readers200;int index;rq;struct wqueue/寫者等待隊列int writers200;int index;wq;/*void first() /初始化int i;rq.index = 0;wq.index = 0;for(i = 0;i<20;i+)rq.readersi = 0;wq.writersi = 0;*/*讀進程讀操作void read()int i = 0;read_id+;if(rcount =

5、0)/當(dāng)前沒有讀進程在讀 可能有寫進程在寫 可能CPU空閑if(w=1) /如果CPU空閑,讀者拿到CPUw-;/ 相當(dāng)于一個P操作rcount+;if(temp0 = '0')sign = 0;if(choice = 1)rq.readersrq.index+=read_id;/將讀者進程加入等待隊列RFwakeup();return;elserq.readersrq.index+=read_id;/將讀者進程加入等待隊列WFwakeup();return;/ifprintf("讀者%d正在讀n",read_id);for(i = 0;i < 300

6、;i+)/讀取temp內(nèi)容 即寫者寫的內(nèi)容if(tempi = '0')printf("n");return;/ifprintf("%c",tempi);/for/ifelse/寫者線程正在執(zhí)行printf("!有寫者在寫不能讀!n");rq.readersrq.index+=read_id;/將讀者進程加入等待隊列/else/ifelse/rcount !=1 則知道當(dāng)前已經(jīng)有讀者在讀,讀讀不互斥,則這個讀者可以直接進來了讀printf("讀者%d正在讀n",read_id);for(i = 0;

7、i < 300;i+) if(tempi = '0')printf("n");return;printf("%c",tempi);/for/else/*寫進程寫操作void write()write_id+;if(w = 0)if(rcount != 0 )/有讀者進程在執(zhí)行printf("!有讀者在讀不能寫!n");wq.writerswq.index+=write_id;/將寫者進程加入等待隊列wcount+;return;if(rcount = 0 )/rcount = 0則當(dāng)前無讀者,但w = 0,所以有

8、寫者在寫printf("!有寫者在寫不能寫!n");wq.writerswq.index+=write_id;/將寫者進程加入等待隊列wcount+;return;if(w = 1)w-;printf("寫者%d正在寫n請輸入要寫的內(nèi)容",write_id); scanf("%s",temp);/while/if/*讀者優(yōu)先時喚醒進程void RFwakeup()int i = 0;int j = 0;int m,n;m = rq.index;/n = wq.index;if(rcount = 0)/當(dāng)前無讀進程,是寫者在寫 -停止運

9、行寫進程bool reader_wait=false; w=1;printf("寫者已經(jīng)寫完n");sign = 1;/temp中已經(jīng)有內(nèi)容 要置1for(i=0;i<=m;i+)/index為當(dāng)前讀者隊列中的等待進程數(shù)if(rq.readersi!=0)reader_wait=true; /確實有讀者在等待printf("等待的讀者%d正在讀n",rq.readersi);w = 0;for(j = 0;j < 300;j+)if(tempj = '0')printf("n");break;/ifprin

10、tf("%c",tempj);/forrq.readersi=0;rcount+;rq.index-;/if/forif(!reader_wait)/沒有讀者等待,看是否有寫者等待for(int i=0;i<=wq.index;i+)/檢查寫者等待隊列if(wq.writersi!=0)w = 0;printf("等待的寫者%d正在寫n請輸入要寫入的內(nèi)容",wq.writersi);scanf("%s",temp);wq.writersi=0;wcount-;break;/if/for/if/return;/ifelse/rco

11、unt != 0讀者正在讀,stop讀此時若有等待必為寫者rcount=0;w = 1;if(sign = 0)printf("緩沖區(qū)空 等待寫者n");return;elseprintf("讀者已經(jīng)讀完n");for(int i=0;i<=wq.index;i+)/檢查寫者等待隊列if(wq.writersi!=0)w = 0;printf("等待的寫者%d正在寫n請輸入要寫入的內(nèi)容",wq.writersi);scanf("%s",temp);wq.writersi=0;wcount-;break;/if

12、/for/else/*寫者優(yōu)先喚醒void WFwakeup()int i = 0;int j = 0;int m,n;m = rq.index;/n = wq.index;if(rcount = 0)/當(dāng)前無讀進程,是寫者在寫 -停止運行寫進程bool writer_wait=false; w=1;printf("寫者已經(jīng)寫完n");sign = 1;/temp中已經(jīng)有內(nèi)容 要置1for(i=0;i<=wq.index;i+)/index為當(dāng)前寫者隊列中的等待進程數(shù)if(wq.writersi!=0)writer_wait=true; /確實有寫者在等待printf

13、("等待的寫者%d正在寫n 請輸入要寫的內(nèi)容n",wq.writersi);w = 0;scanf("%s",temp);wq.writersi=0;wcount-;break;if(!writer_wait)/沒有xie者等待,看是否有du者等待for(int i=0;i<=m;i+)/檢查寫者等待隊列if(rq.readersi!=0)w = 0;printf("等待的讀者%d正在讀n",rq.readersi);for(j = 0;j < 300;j+)if(tempj = '0')printf(&q

14、uot;n");rq.index-;break;/ifprintf("%c",tempj);/forrq.readersi=0;rcount+;/if/for/if/return;/ifelse/rcount != 0讀者正在讀,stop讀此時若有等待必為寫者rcount=0;w = 1;printf("讀者已經(jīng)讀完n");for(int i=0;i<=wq.index;i+)/檢查寫者等待隊列if(wq.writersi!=0)w = 0;printf("等待的寫者%d正在寫n請輸入要寫入的內(nèi)容",wq.writer

15、si);scanf("%s",temp);wq.writersi=0;wcount-;break;/if/forvoid menu1()char i;printf(" 1-創(chuàng)建讀者進程n 2-創(chuàng)建寫者進程n 3-結(jié)束當(dāng)前執(zhí)行的進程n 4-退出程序n");printf("*n");doprintf("當(dāng)前隊列中有讀者: %d個 寫者: %d個n",rq.index,wcount);printf("*n");printf(" ->");scanf("%s"

16、;,&i);switch(i)case '1':read();break;case '2':write();break;case '3':RFwakeup();break;case '4':exit(0);default:printf("輸入錯誤請重新輸入n");while(true);void menu2()char i;printf(" 1-創(chuàng)建讀者進程n 2-創(chuàng)建寫者進程n 3-結(jié)束當(dāng)前執(zhí)行的進程n 4-退出程序n");printf("*n");doprin

17、tf("當(dāng)前隊列中有讀者: %d個 寫者: %d個n",rq.index,wcount);printf("*n");printf(" ->");scanf("%s",&i);switch(i)case '1':read();break;case '2':write();break;case '3':WFwakeup();break;case '4':exit(0);default:printf("輸入錯誤請重新輸入n"

18、);while(true);void main()printf("*n");printf(" 20092104實驗一n 1.讀者優(yōu)先n 2.寫者優(yōu)先n");scanf("%d",&choice);while(1)if(choice = 1)menu1();if(choice = 2)menu2();if(choice != 1 && choice != 2)printf("輸入錯誤請重新輸入n");scanf("%d",&choice);實驗流程圖:開始退出寫者優(yōu)

19、先讀者優(yōu)先結(jié)束寫者優(yōu)先喚醒讀者優(yōu)先喚醒寫操作讀操作是否有讀者在讀有寫者 讀者入隊是否有讀者在讀NYNNCPU是否空閑有讀者 寫者入隊YCpu是否空閑進行讀操作YYN進行寫操作緩沖區(qū)是否為空讀操作N有寫者,寫操作入隊Y入讀者等待隊列調(diào)用讀者優(yōu)先喚醒讀者優(yōu)先喚醒Y當(dāng)前有無讀者在讀N有無讀者等待NY讀者出隊進行讀操作直到讀者隊空有無寫者等待YN進行寫操作N緩沖區(qū)是否為空返回Y有讀者說明若有等待必為寫者寫者優(yōu)先喚醒Y當(dāng)前有無讀者在讀N有無寫者等待NY寫者出隊進行寫操作直到寫者隊空有無讀者等待Y進行讀操作直到讀者隊列為空N寫者隊列是否為空返回YN進行寫操作直到寫者隊列為空核心部分設(shè)計思路:分別用兩個隊列

20、來存放等待的讀者進程和寫者進程,一個進程結(jié)束后就要將因他阻塞的進程喚醒,如果是讀者優(yōu)先,則先檢查讀者進程,如果發(fā)現(xiàn)讀者進程不為空,就進行讀操作,直到讀者進程為空,才進行寫操作;同理,如果是寫者優(yōu)先,則先檢查寫進程,如果發(fā)現(xiàn)寫者進程不為空,就進行寫操作,直到寫者進程為空,才進行讀操作。讀寫互斥:只有當(dāng)互斥信號量w = 1并且當(dāng)前讀者數(shù)為0時,才可以進行寫操作,對于讀進程,w = 1且當(dāng)前讀者數(shù)為0時,第一個讀進程進行讀操作,當(dāng)當(dāng)前讀者數(shù)大于0時,不用判斷互斥信號量w而直接進行讀操作。對緩沖區(qū)為空的情況,如果緩沖區(qū)為空時進行讀操作,則會設(shè)置一個信號量標(biāo)志緩沖區(qū)為空sign = 0,不可以進行讀操作

21、,釋放出CPU,調(diào)用喚醒函數(shù)喚醒寫進程,此時會將此進程放入讀者進程等待隊列中等待寫者來寫數(shù)據(jù)再進行讀操作,寫者寫完數(shù)據(jù),緩沖區(qū)不空時,將標(biāo)志置為緩沖區(qū)不空sign = 1。編譯過程中遇到的問題:1. 編譯過程中出現(xiàn)的一個很大的錯誤就是在構(gòu)造隊列的時候給變量index賦值了,系統(tǒng)提示錯誤解決:取消賦值,編寫了一個初始化函數(shù)進行初始化,后來發(fā)現(xiàn)不初始化也沒用什么問題,就注釋掉了。2. 剛開始還會出現(xiàn)一些括號不匹配的錯誤,在后來的程序完善過程中,盡量給后括號做一個注釋進行標(biāo)識。運行過程中遇到的問題:1. 不能接受非法字符,如果輸入非法字符就會進入死循環(huán),但是在switch外明明有檢查語句。解決:通過單步跟蹤,發(fā)現(xiàn)檢查語句并沒有起到作用,于是調(diào)整了一下結(jié)構(gòu),將檢查語句放到switch里,既起到了檢查的作用,同時也減少了代碼量。2. 在讀者進行讀取數(shù)據(jù)時,總是會在讀取完寫者寫的內(nèi)容的后面出現(xiàn)一個小a。解決:也是通過單步跟蹤,發(fā)現(xiàn)是判空和輸出的順序問題,如果先輸出后判空的話,會多進行一次循環(huán),導(dǎo)致輸出一個小a,但是現(xiàn)在還是不太明白為什么多輸出的是小a。3. 當(dāng)緩沖區(qū)為空的時候創(chuàng)建了

溫馨提示

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

評論

0/150

提交評論