生产者消费者算法是经典的进程同步算法,下面就是运用C++模拟实现生产者消费者算法,能实现对缓冲池的互斥访问和生产者进程与消费者进程之间的同步。
实现思路:用C++写一个生产者和消费者类,在里面有一个构造函数,初始化指向产品的指针,产品数和互斥信号量mutex(互斥访问count),接下来就写了生产者和消费者算法,这里要注意的是:缓冲区满时不能生产,缓冲区空时不能消费,这里我都在运行中有提示。主函数中就是循环调用生产者消费者,然后每次调用后输出缓冲区的产品状态和数量。
源代码:
#include <iostream>
#include <time.h>
#include <stdlib.h>
#define N 100 //产品数量
using namespace std;
/*生产者消费者类*/
class PandC{
private:
int in,out;//指向有产品的下标
int count;//缓冲区的产品数
int buffer[N];//缓冲区
int mutex;//互斥信号量
int empty,full;//判断缓冲区是否为空或者满
public:
/*初始化,构造生产者消费者*/
PandC(){
in=0;out=0;count=0;
empty=N;full=0;mutex=1;
for(int i=0;i<N;i++)
buffer[i]=0;
}
/*生产者生产*/
void Producer(){
if(empty==0){
full=1;
cout<<"产品已满,不能再生产"<<endl;
return ;
}
Wait(empty);//empty--;
buffer[out]=1; //生产一个产品
out=(out+1)%N; //尾指针后移一位,构成循环队列
cout<<"生产者生产了一个产品"<<endl;
/*对count互斥访问*/
Wait(mutex);
count++;
Signal(mutex);
}
/*消费者消费*/
void Consumer(){
if(empty==N){
cout<<"没有产品,不能消费"<<endl;
return ;
}
buffer[in]=0;//消费一个产品
in=(in+1)%N;//头指针后移一位,构成循环队列
cout<<"消费者消费了一个产品"<<endl;
/*对count互斥访问*/
Wait(mutex);
count--;
Signal(mutex);
if(empty<=N){
full=0;
Signal(empty);//empty++;
}
}
/*显示现在缓冲区的情况*/
void Display(){
for(int i=0;i<N;i++)
cout<<buffer[i];
cout<<endl<<"一共有"<<count<<"个产品"<<endl<<endl;
}
void Wait(int &s){
if(s<=0) return ;
s--;
}
void Signal(int &s){
s++;
}
};
int main(){
int i=0;
srand(time(NULL));
PandC x;
/*随机执行生产者生产还是消费者消费*/
do{
if(rand()%100>80)//利用比例控制生产速度
x.Producer();
else
x.Consumer();
x.Display();
i++;
}while(i!=1000);
return 0;
}
简单实现了生产者消费者算法,用0,1表示有没有产品,还是过于抽象了,如果能用进度条那种形式就更好了,但是能力有限,只是实现了其中的算法思想,还是需要学习,改进。