生产者消费者算法模拟 c++

0
8

运行结果

流程图

废话不多说,直接上代码

  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 }

  

<

发布回复

请输入评论!
请输入你的名字