PV操作哲學家問題和生產者-消費者問題剖析_第1頁
PV操作哲學家問題和生產者-消費者問題剖析_第2頁
PV操作哲學家問題和生產者-消費者問題剖析_第3頁
PV操作哲學家問題和生產者-消費者問題剖析_第4頁
PV操作哲學家問題和生產者-消費者問題剖析_第5頁
已閱讀5頁,還剩5頁未讀 繼續免費閱讀

下載本文檔

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

文檔簡介

1、PV操作(哲學家問題)給每個哲學家編號,規定奇數號的哲學家先拿他的左筷子,然后再去拿他的右筷子;而偶 數號的哲學家則相反。這樣總可以保證至少有一個哲學家可以進餐。include include include processhinclude include using namespace std;DWORD WINAPI philosopher(LPVOID IpParameter);void thinking(int):void eating(int);void waiting(int);void print(int ,const char *);全局變量CRITICAL_SECTION c

2、rout;/這個變量用來保證輸出時不會竟7CRITICAL_SECTION fork5;/定義五個臨界變量,代表五更筷J: int main(int argc, char *argv)HANDLE hthread5;int i;int arg5;int count = 5;long a=0;unsigned long retval:InitializeCriticalSection(&crout);初始化臨界變量for(i=0;i5;i+)InitializeCriticalSection(fork + i):/創建五個哲學家for(i = 0; i5;i+)argi = i;hthreadi

3、 = CreateThread(NULL, 0, philosopher, (void*) (arg-i), 0, NULL); for(a=0;a30000000;a+);if( hthreadCi = INVALID_HANDLE_VALl:E)/如果線程創建失敗返回Tcerr error while create thread i endl;cerr ,zerror code : GetLastError 0 endl;等待所有線程結束retval = WaitForMultipleObjects (5, hthread, true, INFINITE); /等待多個線程 for(a=0

4、;a30000000:a+);if(retval = WAIT.FAILED)cerr wait error, error code: z,GetLastError0endl;for(i = 0; i5;i+)for(a=0;a30000000;a+);i f (C loseHandl e (ht hread i ) = false) /關閉句柄cerr error while close thread iendl;cerr ,zerror code: /zGetLastError0endl;return 0;DWORD WINAPI ph訂osopher(LPVOID IpParameter

5、) long a=0;int n = (int *)IpParameter)0;for(a=0;a30000000:a+):print(n, is in!);/srand(time(NULL);while(true)thinking(n); waiting(n); eating(n);print(n, is out!);return n;void thinking(int k)long a=0;for(a=0;a30000000;a+):print (k, is thinking);Sleep (1);/Sleep(rand0 %100) *5);void eating(int k)long

6、a=0;for(a=0;a30000000;a+):print (k, is eating);/Sleep(rand 0%100) *5);Sleep (1);LeaveCriticalSection(fork + (k+l)%5); / /放下右邊的筷子/print(k, give left);LeaveCriticalSection(fork + k); /放下左邊的筷子/./print (k, give right);void waiting(int k)long a=0;for(a=0;a30000000;a+):print(k, is waiting);Sleep (1);Enter

7、CriticalSection(fork + k) ;/獲得左邊的筷子/print(k, take left);EnterCriticalSection(fork + (k + 1)%5);/獲得右邊的筷子/print(k, take right);void print(int who, const char *str)tvpedefint semaphore; /*信號量是一種特殊的整型變量*/semaphore mutex=l; /* 互斥訪問 */semaphore emptv=N;/*記錄緩沖區中空的槽數*/semaphore fiill=0; /*記錄緩沖區中滿的槽數*/semaph

8、ore buffN; /*有N個槽數的緩沖區bufN,并實現循環緩沖隊列*/ semaphore front=0, rear=0;void p(seniaphore *x) /* p 操作 */ *x=(*x)-l;void v(semaphore *v)/* v 操作 */*y=(*y)+i;void produce_item(int *item_ptr)/*pnntf(Mpioduce ail itemnn);*/*item_ptr=,m,; /* nf is Mmaii 滿;*/ void enter_item(mt x)fiont=(fiont+1 )%N;buffront=x;pnn

9、tf(Mentei_item %c to buf%dn, buffront, front);void remove_item(int *yy)reai(reai+l)%N;printfCemovetem %c fiom buff%d, buffieai, rear);*yy=bufrear;buflreai; /* k is nkong 空” */ pnntf(M so the buff%d changed to empty%ciiH, fear, bufrear);void consume_item(mt y)printf(Mcosume tlie item :tlie screem pri

10、nt %cn9 y); void producer(void); void consumer(void);/*生產者*/void producer(void) mt item;wlule(l)produce_item(&item);p(&emptv);/*遞減空槽數*/p(&mutex);/*進入臨界區*/enter_item(item); /*將一個新的數據項放入緩沖區*/ V(&mutex);/*離開臨界區*/v(&hill);/*遞增滿槽數/if(fiill=N)/*若緩沖區滿的話,喚醒消費者進程*/consumerQ;/*消費者*/void consumer(void) mt get_

11、item;wlule(l)p(&fbll);/*遞減滿槽數*/p(&mutex);/*進入臨界區/remove_item(&g亡/*從緩沖區中取走一個數據項*/ v(&mutex);/*離開臨界區*/v(&empty);/*遞增空槽數*/consume_item(get_item);/*對數據項進行操作(消費)*/ if(empty=N)/*若緩沖區全空的話,喚生產者進程*/pioducerO;/*調用生產者一消費者進程實現進程間同步*/ niaui()producer();return 0;EEE:0Ssample1Debugsample1.execosune the item :the s

12、creen tt*enoueitem m from buf 2 Losume tlie item : tlie screen tt*enoue_iten m from buf 3 cosune the item :the screen tt*enoueitem m from buf4 cosune the item :the screen tt*enoue_iten m from buf 5 cosune the item :the screen tt*enoue_iten m from buf 6 cosune the item :the screen kemoue_item m f i*o

13、m hif T71 cosune the item :the screen tt*enoueitem m from buf 8 cosune the item :the screen tt*enoueitem m from buf 9 cosune the item :the screen 卜emoue_item m from huf0 item to to to to tocosune the enter_item enter_item enter_item enter_item enter_item傲軌拼首豐::the screen buf 1 buf 12 buf L3 bufL4 bu

14、fL4I printnso thebufL2changedtoemptyki printinso thebuf3changedtoemptyki printnso thebuf4changedtoemptyki printnso thebufL5changedtoemptyki printnso thebuf6changedtoemptyki printnso thebufT71changedtoemptyki printnso thebuf8Jchangedtoemptyki printnso thebuf9changedtoemptyki printnso thebuf0changedto

15、emptyki printn生產者消費者問題解決方法二:因為實際情況是生產消費速度不會一致,也不會想方法一一樣,消費完后在生產。我們 生產者要保持滿足消費者的需求。調整下面的數值,可以發現,當生產者個數多于消費者個 數時,生產速度快,生產者經常等待消費者:反之,消費者經常等待,可以保證消費者可以 一直消費。實現代碼:?tinclude #include const unsigned short SIZE_OF_BUFFER = 10; /緩沖區長度unsigned short ProductID = 0;unsigned short ConsumelD = 0;/產品號將被消耗的產品號unsi

16、gned short in = 0;產品進緩沖區時的緩沖區下標unsigned short out = 0;產品出緩沖區時的緩沖區下標int g.bufferSIZE.OF.BUFFER;/緩沖區是個循環隊列bool g_continue = true;/控制程序結束HANDLE g_hMutex;/用于線程間的互斥HANDLE g.hFullSemaphore;當緩沖區滿時迫使生產考等待HANDLE g.hEmptySemaphore;/當緩沖區空時迫使消費者等待DWORD WINAPI Producer (LPVOID); /生產者線程DWORD WINAPI Consumer (LPVO

17、ID); /消費者線程int mainO創建各個互斥信號g.hMutex = CreateMutex(XULL, FALSE, NULL);g.hFullSemaphore = CreateSemaphore(NULL, SIZE.OF.BUFFER-l, SIZE_OF_BUFFER-1,NULL); g_hEmp15rSemaphore = CreateSemaphore (NULL, 0, SIZE_OF_BUFFER-1, NULL);調整下而的數值,可以發現,當生產者個數多于消費者個數時,/生產速度快,生產者經常等待消費者:反之,消費者經常等待const unsigned short

18、 PRODUCERS.COUNT = 3;/生產者的個數const unsigned short CONSUMERS.COUNT = 1;/消費者的個數總的線程數const unsigned short THREADS.COUNT = PRODUCERS.COUNT+CONSUNERS.COUNT:HANDLE hThreadsPRODUCERS_COUNT; 各線程的handleDWORD producer ID CONSUMERS.COUNT; /生產者線程的標識符DWORD consumer ID THREADS.COUXT: /消費者線程的標識符創建生產者線程for (int i=O;

19、iPRODUCERS_COUNT;+i)hThreadsiJ =CreateThread(NULL, 0, Producer, NULL, 0, &producerIDi);if (hThreadsi=NULL) return -1;創建消費者線程for ( int i=0;iC0NSl3ERS_C0UNT:+i)hThreadsPRODUCERS_COUNT+i=CreateThread(NULL, 0, Consumer, NULL, 0, &consumerIDi);if (hThreadsi=NULL) return -1;while(g_continue) if(getchar()

20、按回車后終止程序運行g_continue = false;return 0;生產一個產品。簡單模擬了一下,僅輸出新產品的ID號void Produce 0std:cerr Producing +ProductID std:cerr Succeed std:endl;/把新生產的產品放入緩沖區void Append0std:cerr ,zAppending a product g_bufferlinZ = ProductID;in = (in+l)%SIZE_OF_BUFFER;std:cerr Succeed std:endl;/輸出緩沖區當前的狀態for (int i=O;iSIZE_OF_

21、BUFFER;+i) std:cout i : g_bufferi; if (i=in) std:cout - 生產; if (i=out) std:cout 消費; std:cout std:endl;從緩沖區中取出一個產品void Take 0std:cerr Taking a product ”; ConsumeID = g_bufferout:out = (out+1)%SIZE_OF_BUFFER;std:cerr Succeed std:endl;/輸出緩沖區當前的狀態for (int i=O;iSIZE_OF_BUFFER;+i) std:cout i : g_bufferi; if (i=in) std:cout - 生產; if (i=out) std:cout 消費; std:cout std:endl:/消耗一個產品voi

溫馨提示

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

評論

0/150

提交評論