生產者消費者算法模擬 c++


 

 

運行結果

 

流程圖

廢話不多說,直接上代碼 

  1 #include<iostream>
  2 #include <string> 
  3 #include <unistd.h> //sleep函數庫文件
  4 #include<process.h>
  5 #include<windows.h>//句多線程柄庫文件 
  6 #define n 10 //緩沖區大小 
  7 #define sleepTime 2 //控制生產者消費者的生產和消費速度,便於演示觀察 
  8 #define executime 3000//模擬生產消費者算法的時間長 
  9 using namespace std;
 10 
 11 typedef HANDLE semaphore; //互斥信號量句柄 
 12 typedef int item; //緩沖池中產品類型
 13 
 14 item buffer[n] = {0}; //定義緩沖池,並全部置空 
 15 int in = 0; 
 16 int out = 0;
 17 int counter = 0;//每當生產者進程向緩沖池中投放(或取走)一個產品后,使counter加1(或減1)。
 18 semaphore mutex , empty , full ;//定義互斥信號量句柄
 19 
 20 //模擬算法中涉及的課外知識
 21 
 22 //HANDLE WINAPI CreateSemaphore( _In_opt_LPSECURITY_ATTRIBUTES lpSemaphoreAttributes ,_In_LONG lInitialCount, _In_ LONG lMaximumCount,_In_opt_? LPCTSTR lpName
 23 //);
 24 //第一個參數:安全屬性,如果為NULL則是默認安全屬性
 25 //第二個參數:信號量的初始值,要>=0且<=第三個參數
 26 //第三個參數:信號量的最大值
 27 //第四個參數:信號量的名稱
 28 //
 29 //返回值:指向信號量的句柄,如果創建的信號量和已有的信號量重名,那么返回已經存在的信號量句柄
 30 //
 31 //DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);
 32 //
 33 //第一個參數:等待對象的 handle(代表一個核心對象)。
 34 //第二個參數:等待的最長時間。時間終了,即使 handle尚未成為激發狀態,此函數也要返回。此值可以是0(代表立刻返回),也可以是 INFINITE代表無窮等待。
 35 //
 36 //BOOL WINAPI ReleaseSemaphore( _In_ HANDLE hSemaphore,_In_ LONG lReleaseCount,_Out_opt_ LPLONG lpPreviousCount);
 37 //第一個參數:信號量句柄
 38 //第二個參數:釋放后,信號量增加的數目
 39 //第三個參數:信號量增加前的值存放的地址,如果不需要則為NULL
 40 //返回值:釋放是否成功
 41 //void wait(semaphore &S)
 42 //{    
 43 //    while (S<=0);
 44 // S=S-1;
 45 //}
 46 //
 47 //void signal(semaphore &S)
 48 //{ 
 49 //    S=S+1;
 50 //}
 51 //
 52 
 53 void display(string str)
 54 {
 55 cout<<str<<endl;
 56 cout<<"緩沖池:";
 57 for(int i=0;i<n;i++){
 58 cout<<buffer[i]<<' ';
 59 // sleep(1); 減慢輸出速度     
 60 }
 61 cout<<endl;
 62 cout<<"counter:"<<counter<<endl<<endl;
 63 //cout<<" mutex:"<<mutex<<" empty:"<<empty<<" full:"<<full<<endl<<endl; 由於是互斥信號量句柄,無法直接訪問其值 
 64 }
 65 
 66 unsigned __stdcall producer(void*)
 67 {
 68 do{
 69 WaitForSingleObject(empty, INFINITE);//等待同步信號量empty
 70 WaitForSingleObject(mutex, INFINITE);//等待互斥信號量mutex
 71 item nextp=1;    
 72 buffer[in]=nextp;
 73 in=(in+1)%n;
 74 counter++;
 75 display("生產一件產品");
 76 
 77 sleep(sleepTime); 
 78 ReleaseSemaphore(mutex, 1, NULL);//釋放互斥信號量mutex
 79 ReleaseSemaphore(full, 1, NULL);//釋放同步信號量full    
 80 
 81 }while(1);
 82 return 1;
 83 }
 84 
 85 unsigned __stdcall consumer(void* )
 86 {
 87 do{
 88 WaitForSingleObject(full, INFINITE);//等待同步信號量full
 89 WaitForSingleObject(mutex, INFINITE);//等待互斥信號量mutex
 90 item nextc=buffer[out]; 
 91 buffer[out]=0;
 92 out=(out+1)%n;
 93 counter--;    
 94 sleep(sleepTime); 
 95 display("消費一件產品");
 96 ReleaseSemaphore(mutex, 1, NULL);//釋放互斥信號量mutex
 97 ReleaseSemaphore(empty, 1, NULL);//釋放信號量    
 98 }while(1);
 99 return 2;
100 }
101 
102 int main(){
103 int buf_max=n;//輸入緩沖區大小,整形變量,大於0,建議在10—20之間一個整數 ,這里為定義的宏n 
104 int producerNum; //輸入生產者數量,整形變量,建議在4-8,直接,否則太大電腦跑不動,太小生產速度不夠 
105 int consumerNum;//輸入消費者數量,整形變量,建議小於生產者數量,不要為 0
106 cout<<"請輸入生產者數量:";cin>>producerNum;
107 cout<<"請輸入消費者數量:";cin>>consumerNum; 
108 empty = CreateSemaphore(NULL, buf_max, buf_max, NULL); //初值為緩沖池大小,最大為緩沖池大小
109 full = CreateSemaphore(NULL, 0, buf_max, NULL); //初值為0,最大為緩沖池大小
110 mutex = CreateSemaphore(NULL,1,1,NULL); //初值為1,最大為1
111 HANDLE hthproducer[producerNum], htconsumer[consumerNum];//定義生產者 消費者線程句柄池大小 
112 
113 //創建線程
114 int i;
115 
116 for(i=0;i<producerNum;i++)
117 {
118 hthproducer[i] = (HANDLE)_beginthreadex(NULL, 0, producer, NULL, 0, NULL);//生產者線程
119 }
120 
121 for(i=0;i<consumerNum;i++)
122 {
123 htconsumer[i] = (HANDLE)_beginthreadex(NULL, 0, consumer, NULL, 0, NULL);//消費者線程
124 }
125 
126 
127 
128 //等待子線程結束
129 for(i=0;i<producerNum;i++) 
130 WaitForSingleObject(hthproducer[i], executime);//在時間executime到達后無論是否激活線程,都會關閉線程 
131 for(i=0;i<consumerNum;i++) 
132 WaitForSingleObject(htconsumer[i], executime);//在時間executime到達后無論是否激活線程,都會關閉線程 
133 
134 //關閉句柄 
135 for(i=0;i<producerNum;i++) 
136 CloseHandle(hthproducer[i]);
137 for(i=0;i<consumerNum;i++)
138 CloseHandle(htconsumer[i]);
139 
140 CloseHandle(empty);
141 CloseHandle(full);
142 CloseHandle(mutex);    
143 
144 cout<<"演示完畢,謝謝觀看"; 
145 
146 
147 return 0;
148 }

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM