生产者和消费者
nepu的恶臭作业
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <vector>
#include <string>
#include <windows.h>
#include <sstream>
#include <random>
#include <Queue>
#define N 3 //产品数量,缓冲池最大数量,想改可以改,随意,数量少点能快速体现堵塞的时候,该程序可以避免死锁。
#define processNum 50 //进程最多个数,也可以改,随意。
using namespace std;
class PCB;
PCB* wakeup(queue<PCB*>*& list);
PCB* block(queue<PCB*>*& list, PCB* pcb);
int food = 0;//纪录缓冲池食物数量
//int morefood = 0;//在生产者手中的食物
//int lessfood = 0;//消费者想要食物但是食物不够,不够的数量
//记录型信号量
typedef struct semaphore //信号量
{
int value; //信号量的值(资源信号量)
queue<PCB*>* list; //信号量队列指针(阻塞队列)
}semaphore;
queue<PCB*> producerCongestionQueue;//等待信号量empty的阻塞队列
queue<PCB*> consumerCongestionQueue;//等待信号量full的阻塞队列
queue<PCB*> shareCongestionQueue;//等待信号量mutex的阻塞队列
int mutex_c = 1;
int full_c = 0;
int empty_c = N;
semaphore Empty = { N, &producerCongestionQueue };
semaphore Full = { 0, &consumerCongestionQueue };
semaphore Mutex = { 1, &shareCongestionQueue };
class PCB {
public:
string name;//进程名称
int code; //进程编号
int pc;//0-6,指令指针、断点
int time;//时间片
int state;//状态(执行1、堵塞0)
char reason;//阻塞原因(mutex、empty、full)
int roleFlag;//生产者1或消费者0
PCB() = default;
static PCB* CreatePcb(char* name) {
PCB* p = (PCB*)malloc(sizeof(PCB));
if (name != NULL) {
p->name = name;
}
else {
p->name = "default";
}
return p;
}
void wait(semaphore* S) {
S->value--;
if (S->value >= 0) //资源条件满足
{
if (this->roleFlag == 1) { //生产者
if (this->pc == 2)
{
cout << this->name << " 成功,生产者申请获取缓冲池,Empty值满足条件" << " Empty值" << Empty.value << endl;
}
else if (this->pc == 3)
{
cout << this->name << " 成功,生产者申请获取缓冲池,Mutex值满足条件" << " Mutex值" << Mutex.value << endl;
}
}
else if (this->roleFlag == 0) //消费者
{
if (this->pc == 1)
{
cout << this->name << " 成功,消费者申请获取缓冲池,Full值满足条件" << " Full值" << Full.value << endl;
}
else if (this->pc == 2)
{
cout << this->name << " 成功,消费者申请获取缓冲池,Mutex值满足条件" << " Mutex值" << Mutex.value << endl;
mutex_c = 0;//占有
}
}
this->pc++;
}
else if (S->value < 0) //资源条件不满足满足
{
this->state = 0; //状态设置为堵塞
if (this->roleFlag == 1) { //生产者不能放,即生产者进程被阻塞
if (this->pc == 2) {
cout << this->name << " 失败,生产者申请获取缓冲池,Empty值不满足条件" << " Empty值" << Empty.value << endl;
}
else if (this->pc == 3) {
cout << this->name << " 失败,生产者申请获取缓冲池,Mutex值不满足条件" << " Mutex值" << Mutex.value << endl;
}
}
else if (this->roleFlag == 0) { //消费者进程被阻塞
if (this->pc == 1) {
cout << this->name << " 失败,消费者申请获取缓冲池,Full值不满足条件" << " Full值" << Full.value << endl;
}
else if (this->pc == 2) {
cout << this->name << " 失败,消费者申请获取缓冲池,Mutex值不满足条件" << " Mutex值" << Mutex.value << endl;
}
}
block(S->list, this); //阻塞进程
}
}
void signal(semaphore* S) {
S->value++;
if (this->roleFlag == 1) //生产者释放对盘子的访问权
{
if (this->pc == 5)
{
cout << this->name << " 成功,生产者释放缓冲池使用权,signal(Mutex)" << endl;
}
else if (this->pc == 6) {
cout << this->name << " 成功,生产者通知其他进程,signal(Full)" << endl;
}
}
else if (this->roleFlag == 0) //消费者释放对盘子的访问权
{
if (this->pc == 4)
{
cout << this->name << " 成功,消费者释放缓冲使用权,signal(Mutex)" << endl;
}
else if (this->pc == 5) {
cout << this->name << " 成功,消费者通知其他进程,signal(Full)" << endl;
}
}
if (S->value <= 0)
{
wakeup(S->list);
}
this->pc++;
if ((this->roleFlag == 0 && this->pc == 6) || (this->roleFlag == 1 && this->pc == 7)) {
cout << "已经完成一个进程===================================================================================" << this->name << endl;
cout << "name:" << this->name << "code:" << this->code << "pc:" << this->pc << "state:" << this->state << endl;
this->pc = 1;
}
}
};
PCB process[processNum]; //进程集合,roleFlag属性 1生产者,0消费者
PCB* wakeup(queue<PCB*>*& list) {
PCB* p = (*list).front();
int code = p->code;
process[code].state = 1; //进程置为就绪态
if (process[code].roleFlag == 1) { //生产者
if (process[code].pc == 2)
{
cout << process[code].name << " 被唤醒,发现缓冲池不是满的" << " 缓冲池中食物数量" << food << "Full值" << Full.value << endl;
}
if (process[code].pc == 3)
{
cout << process[code].name << " 被唤醒,发现没有其他进程占有缓冲池" << "互斥变量" << Mutex.value << endl;
mutex_c = 1;
}
}
if (process[code].roleFlag == 0) //消费者
{
if (process[code].pc == 1)
{
cout << process[code].name << " 被唤醒,发现缓冲池中有食物" << " 食物数量" << food << " Full值" << Full.value << endl;
}
if (process[code].pc == 2)
{
cout << process[code].name << " 被唤醒,发现没有其他进程占有缓冲池" << " 互斥变量" << Mutex.value << endl;
}
}
process[code].pc++;
(*list).pop(); //删除队首进程
return p;
}
PCB* block(queue<PCB*>*& list, PCB* pcb) {
(*list).push(pcb);
PCB* cur = list->front();
process[pcb->code].state = 0; //进程设置为阻塞态
return pcb;
}
/*生产者消费者类*/
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(PCB* pro) {
int tim = rand() % 10 + 1;
switch (pro->pc)
{
case 1: //1 生产物品
cout << pro->name << " 生产者正在生产食物" << "所需时间" << tim << "秒" << endl;
Sleep(tim * 100);//其实没有等待足够的tim,缩小了十倍,比如假设等8秒实际等了800毫秒
/// <summary>
/// 生产者生产后如果不能放入缓冲池,那么这份食物就拿在手里,然后把该线程挂到阻塞队列中。
/// </summary>
/// <param name="pro"></param>
pro->pc++;
cout << pro->name << " 生产者生产时间" << tim << "秒" << "缓冲池中食物数量" << food << "个" << endl;
break;
case 2: //2 申请空盘子
Sleep(350);
cout << pro->name << " 生产者查看缓冲池是否满了wait(empty)" << endl;
pro->wait(&Empty);
break;
case 3: //3 申请的盘子访问权
Sleep(350);
cout << pro->name << " 生产者查看是否有人使用缓冲队列wait(mutex)" << endl;
pro->wait(&Mutex);
break;
case 4: //4 放入食物
Sleep(350);
food++;
cout << pro->name << " 放入食物" << "缓冲池中有食物" << food << "个" << " Full值为(二值不一致说明由消费者进程堵塞)" << Full.value << endl;
pro->pc++;
break;
case 5: //5 释放对盘子的访问权
Sleep(350);
cout << pro->name << " 释放缓冲队列控制权signal(mutex)" << endl;
pro->signal(&Mutex);
break;
case 6:
//6 水果已经放入盘子 ,通知两个消费者
Sleep(350);
cout << pro->name << " 已经完成生产过程通知消费者signal(full)" << endl;
pro->signal(&Full);
pro->pc = 1;
break;
}
}
/*消费者消费*/
void Consumer(PCB* pro) {
switch (pro->pc)
{
case 1: //1 申请从盘子中拿水果
Sleep(350);
cout << pro->name << " 消费者提出申请拿走食物wait(full)" << " 当前缓冲池中食物数量" << food << "当前full值" << Full.value << " 二者不一致表示有生产者虽然放置了食物但是没有signal操作完毕" << endl;
/*注意:这里放置sleep是假设下几个时间片执行的时候这里刚好生产完毕,简化了操作,抽象理解,这里只是简单模拟,实际上其他时间片结束后这里才生产完毕*/
pro->wait(&Full);
break;
case 2: //2 申请盘子的访问权
Sleep(350);
cout << pro->name << "消费者获得拿走食物的申请wait(mutex)" << endl;
pro->wait(&Mutex);
break;
case 3: //3 从盘子里取水果
Sleep(350);
food--;
cout << pro->name << " 消费者拿走食物" << endl;
pro->pc++;
break;
case 4: //4 释放对盘子的访问权
Sleep(350);
cout << pro->name << " 消费者释放访问权signal(mutex)" << endl;
pro->signal(&Mutex);
break;
case 5: //5 已经从盘子里取走水果,通知父亲放水果
Sleep(350);
cout << pro->name << " 消费者拿走食物signal(empty)" << endl;;
pro->signal(&Empty);
pro->pc = 1;
break;
}
}
};
void initProcess(int pN, int cN)//初始化函数 pN生产者个数,cN消费者个数
{
int i = 0;
for (; i < pN; i++) {
process[i].name = to_string(i + 1) + "号生产者进程";
process[i].roleFlag = 1;
process[i].state = 1;//就绪状态
process[i].pc = 1;//第一步
process[i].code = i;
}
for (; i < cN + pN; i++)
{
process[i].name = to_string(i + 1) + "号消费者进程";
process[i].roleFlag = 0;
process[i].state = 1;//就绪状态
process[i].pc = 1;//第一步
process[i].code = i;
}
}
int main() {
int i = 0;//时间片执行次数
/*随机执行生产者生产还是消费者消费*/
int ci = 0;
printf(">>>>>>>>>>>>>>>>>>>>>>>>>(一下所有数字都是正整数)>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
printf("请输入时间片执行次数,用于模拟多进程,请输入较大的值如(50):");
cin >> ci;
cout << "请输入生产者个数,消费者个数,空格分隔,输入1 1表示单消费者和单生产者模型";
int pN = 0, cN = 0;
cin >> pN >> cN;
printf("执行时间片%d次\n", ci);
printf(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n\n\n");
initProcess(pN, cN);
printf(">>>>>>>>>>>>>>>>>>>>Process begins......>>>>>>>>>>>>>>>>>>>>>>>\n");
PandC factory;
PCB* cur;
int a = 0;
//Mutex.value = pN + cN - 1;
//定义均匀分布对象,均匀分布区间(a,b)为(0,pN+cN)
uniform_int_distribution<int> uid{ 0,pN + cN - 1 };
//定义随机数种子
random_device rd;
//定义默认随机数生成器
default_random_engine dre{ rd() };
do {
//srand(time(NULL));
//a = rand() % (pN+cN)+1;
a = uid(dre);
cur = &process[a];
cout << cur->name << ":" << "full:" << Full.value << " mutex:" << Mutex.value << " empty:" << Empty.value << " code:" << cur->code << " pc:" << cur->pc << " state:" << cur->state << endl;
if (!cur->state) {
continue;
}
if (cur->roleFlag == 1) {
factory.Producer(cur);
}
else {
factory.Consumer(cur);
}
i++;
cout << "时间片执行次数============================" << i << endl;
} while (i != ci);
cout << "时间片执行" << ci << "次" << "最终执行结果:" << endl;
cout << "full:" << Full.value << endl;
cout << "empty:" << Empty.value << endl;
cout << "mutex:" << Mutex.value << endl;
cout << "food:" << food << endl;
return 0;
}
老师:“你们就简单实现以下就行”