操作系统:用c++模拟生产者消费者问题
一.实验目的:通过实验模拟生产者与消费者之间的关系,了解并掌握他们之间的关系及其原理。由此增加对进程同步的问题的了解。
二.实验要求:每个进程有一个进程控制块(PCB)表示。进程控制块可以包含如下信息:进程类型标号、进程系统号、进程状态、进程产品(字符)、进程链指针等等。系统开辟了一个缓冲区,大小由buffersize指定。程序中有三个链队列,一个链表。一个就绪队列(ready)。两个等待队列:生产者等待队列(producer),消费者等待队(consumer)。一个链表(over),用于收集已经运行结束的进程。本程序通过函数模拟信号量的原子操作。
三.实验内容:
1.由用户指定要产生的进程及其类别,且存入进入就绪队列。
2.调度程序从就绪队列中提取一个就绪进程运行。如果申请的资源被阻塞则进入相应的等待队列,调度程序调度就绪队列中的下一个进程。进程运行结束时,会检查对应的等待队列,激活队列中的进程进入就绪队列。运行结束的进程进入over链表。重复这一过程直至就绪队列为空。
3.程序询问是否要继续?如果要转至1开始执行,否则退出程序。
四.实验代码:
#include <iostream>
using namespace std;
int BUFFERSIZE;
int NOW_BUFFER;
typedef struct PCB{
int type;
int num;
int status;
char product;
};
PCB p[100];
typedef struct QNode{
PCB data;
struct QNode *next;
}QNode;
typedef struct {
QNode* front;
QNode* rear;
}LinkQueue;
void InitQueue(LinkQueue &Q){
Q.front=Q.rear=new QNode;
Q.front->next=NULL;
}
bool EnQueue(LinkQueue &Q,PCB e){
QNode* p=new QNode;
p->data=e;
p->next=NULL; Q.rear->next=p;
Q.rear=p;
return true;
}
bool DeQueue(LinkQueue &Q) {
if (Q.front == Q.rear)
return false;
else {
QNode *p = Q.front->next;
Q.front->next = p->next;
if (Q.rear == p)
Q.rear = Q.front;
delete p;
return true;
}
}
PCB GetHead(LinkQueue Q){
PCB m;
m.type=-1;m.num=-1;m.status=-1;m.product='!';
if(Q.front!=Q.rear)
return Q.front->next->data;
else{
return m;
}
}
void TravelQueue(LinkQueue Q){
QNode* p=Q.front;
if(p->next==NULL)
return;
while (p->next->next){
cout<<p->next->data.num<<"-->";
p=p->next;
}
cout<<p->next->data.num;
p=NULL;
}
typedef struct LNode{
PCB data;
struct LNode* next;
}LNode,*LinkList;
void InitList(LinkList &L){
L=new LNode;
L->next=NULL;
}
bool Add(LinkList &L,PCB e){
LinkList s=L;
while(s->next){
s=s->next;
}
LNode* p=new LNode;
p->data=e;
p->next=NULL;
s->next=p;
s=p;
return true;
}
void TravelList(LinkList L){
LNode* p=L;
if(p->next==NULL)
return;
while (p->next->next){
cout<<p->next->data.num<<"-->";
p=p->next;
}
cout<<p->next->data.num;
p=NULL;
}
void Print(LinkQueue &ready,LinkQueue &producer,LinkQueue &customer,LinkList &over){
cout<<"就绪队列为:";
TravelQueue(ready);
cout<<endl;
cout<<"生产者等待队列为:";
TravelQueue(producer);
cout<<endl;
cout<<"消费者等待队列为:";
TravelQueue(customer);
cout<<endl;
cout<<"已完成进程为:";
TravelList(over);
cout<<endl;
cout<<"缓冲区数据量:"<<NOW_BUFFER<<endl;
cout<<"缓冲区剩余存储量:"<<BUFFERSIZE-NOW_BUFFER<<endl;
}
void Process(LinkQueue &ready,LinkQueue &producer,LinkQueue &customer,LinkList &over){
int i=0;
while(ready.front->next!=NULL){
cout<<"------------------------------"<<endl;
cout<<"第"<<i+1<<"轮"<<endl;
PCB first= GetHead(ready);
DeQueue(ready);
if(first.type==0){
cout<<"取就绪队列队头,"<<"该进程为:"<<first.num<<",是生产者进程"<<endl;
NOW_BUFFER++;
if(NOW_BUFFER<=BUFFERSIZE){
PCB t= GetHead(customer);
if(t.num!=-1) {
cout << "检查消费者等待队列,有消费者被阻塞,给予激活并加入就绪队列队头" << endl;
DeQueue(customer);
QNode* r=new QNode ;
if(ready.front!=ready.rear){
r->data=t;
r->next=ready.front->next;
ready.front->next=r;}
else{
r->data=t;
r->next=ready.rear->next;
ready.rear->next=r;
ready.rear=r;
}
Add(over,first);
Print(ready,producer,customer,over);
}
else{
cout << "检查消费者等待队列,没有消费者被阻塞" << endl;
Add(over,first);
Print(ready,producer,customer,over);
}
}
else{
NOW_BUFFER--;
cout<<"缓冲区剩余量不够,该生产者进程被阻塞"<<endl;
EnQueue(producer,first);
Print(ready,producer,customer,over);
}
}
else{
cout<<"取就绪队列队头,"<<"该进程为:"<<first.num<<",是消费者进程"<<endl;
NOW_BUFFER--;
if(NOW_BUFFER>=0){
PCB m= GetHead(producer);
if(m.num!=-1){
cout << "检查生产者等待队列,有生产者被阻塞,给予激活并加入就绪队列队头" << endl;
DeQueue(producer);
QNode* s=new QNode ;
if(ready.front!=ready.rear){
s->data=m;
s->next=ready.front->next;
ready.front->next=s;
}
else{
s->data=m;
s->next=ready.rear->next;
ready.rear->next=s;
ready.rear=s;
}
Add(over,first);
Print(ready,producer,customer,over);
}
else{
cout << "检查生产者等待队列,没有生产者被阻塞" << endl;
Add(over,first);
Print(ready,producer,customer,over);
}
}
else{
NOW_BUFFER++;
cout<<"缓冲区剩数据量不够,该消费者进程被阻塞"<<endl;
EnQueue(customer,first);
Print(ready,producer,customer,over);
}
}
i++;
}
}
int main() {
while(1) {
int number;
LinkQueue ready;
LinkQueue producer, customer;
LinkList over;
InitQueue(ready);
InitQueue(producer);
InitQueue(customer);
InitList(over);
cout << "------------------------------" << endl;
cout << "请输入您要加入的进程数量(0-100):";
cin >> number;
cout << "请输入缓冲区容量:";
cin >> BUFFERSIZE;
NOW_BUFFER = 0;
for (int i = 0; i < number; i++) {
cout << "------------------------------" << endl;
cout << "请输入第" << i + 1 << "个进程信息:" << endl;
cout << "进程类型(0代表生产者,1代表消费者):";
cin >> p[i].type;
cout << "进程号码(0-" << number - 1 << "):";
cin >> p[i].num;
p[i].status = 1;
cout << "进程产品:";
cin >> p[i].product;
}
cout << "------------------------------" << endl;
for (int i = 0; i < number; i++) {
if (p[i].status == 1)
EnQueue(ready, p[i]);
}
Print(ready, producer, customer, over);
Process(ready, producer, customer, over);
cout << "------------------------------" << endl;
cout << "是否继续?(y/n)?" << endl;
char t;
cin>>t;
if (t == 'n') {
exit(0);
}
}
return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)