百度文献查看原文

核心代码:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>
#include<windows.h>
#define dataBufferSize  2        //缓冲区数目
#define processNum 4            //进程数量(生产者、消费者进程总数目)
typedef struct Seamphore          //信号量
{
int value;            //信号量的值
int *pcq;            //信号量队列指针
} Seamphore;
int producerCongestionQueue[processNum];    //等待信号量empty的阻塞队列
int consumerCongestionQueue[processNum];    //等待信号量full的阻塞队列
int shareCongestionQueue[processNum];        //等待信号量mutex的阻塞队列
Seamphore empty={dataBufferSize,producerCongestionQueue}; // empty:空缓冲区数目
Seamphore full={0,consumerCongestionQueue};  // full:缓冲区内可用的产品
Seamphore mutex={1,shareCongestionQueue};    //mutex:互斥信号量
struct DataBuffer          //缓冲区
{
int buffer[dataBufferSize];
int count;                //当前产品数量
}dataBuffer;
typedef struct Process          //进程PCB
{char name[10];                //进程名
int roleFlag;                    //进程类型(1: 生产者  0: 消费者)
int currentState;              //进程状态(1: 就绪态  0: 阻塞态)
int currentStep;              //断点
int data;                        //临时数据
int code;                        //进程编号
}Process;
Process process[processNum];    //进程集合
void moveDataForward()
{
int i;
for (i = 0; i <dataBuffer.count; i++)
dataBuffer.buffer[i] = dataBuffer.buffer[i+1];
}
void push(int data)      //产品送入缓冲区
{
dataBuffer.buffer[dataBuffer.count++] = data;
}
int pop()            //从缓冲区取出产品
{
int data = dataBuffer.buffer[0];
dataBuffer.count--;
moveDataForward();
return data;
}
void initProcess() {            //初始化进程集合
int i;
char digitTemp[5];
srand(time(NULL));
for (i = 0; i <processNum; i++) {process[i].roleFlag = rand()%2;            // 随机指定当前进程为生产者或消费者
if (process[i].roleFlag)
strcpy(process[i].name, "生产者");
else
strcpy(process[i].name, "消费者");
strcat(process[i].name, itoa(i+1, digitTemp, 10));
process[i].currentState = 1;
process[i].currentStep = 1;
process[i].code = i + 1;
producerCongestionQueue[i] = 0;
consumerCongestionQueue[i] = 0;
shareCongestionQueue[i] = 0;
}
}
void wakeup(int *pcq) {                    //唤醒进程
int code = pcq[0] - 1;                //取出队首进程
process[code].currentState = 1;        //进程置为就绪态
//当进程被唤醒后继续执行任务
if (process[code].roleFlag == 1) {        //生产者
if (process[code].currentStep == 2) {printf("%20s: 该进程被唤醒!申请空缓冲区成功!\n", process[code].name);
} else if (process[code].currentStep == 3) {printf("%20s: 该进程被唤醒!申请访问缓冲区成功!\n", process[code].name);
}
} else if (process[code].roleFlag == 0) {    //消费者
if (process[code].currentStep == 1) {process[code].data = pop();
printf("%20s: 该进程被唤醒!申请取产品%d成功!\n", process[code].name, process[code].data);
} else if (process[code].currentStep == 2) {printf("%20s: 该进程被唤醒!申请访问缓冲区成功!\n", process[code].name);
}
}
process[code].currentStep++;
for (int i = 1; (i <processNum) && (pcq[i] != 0); i++) {        //删除队首进程
pcq[i-1] = pcq[i];
if (pcq[i-1] >processNum) {pcq[i-1] = 0;
}
}
}
void sleep(int pcq[], int code) {            //阻塞进程
int i;
process[code-1].currentState = 0;            //进程置为阻塞态
for (i = 0; i <processNum; i++) {if (!pcq[i]) {pcq[i] = code;
break;
}
}
}
void P(Seamphore *s, Process *p) {                //模拟P操作
s->value -= 1;
if (s->value>= 0) {
if (p->roleFlag == 1) {                    //生产者
if (p->currentStep == 2) {printf("%20s: 申请空缓冲区成功!\n", p->name);
} else if (p->currentStep == 3) {printf("%20s: 申请访问缓冲区成功!\n", p->name);
}
} else if (p->roleFlag == 0) {            //消费者
if (p->currentStep == 1) {printf("%20s: 申请取出产品成功!\n", p->name);
} else if (p->currentStep == 2) {printf("%20s: 申请访问缓冲区成功!\n", p->name);
}
}
p->currentStep++;                        //下一步
} else if (s->value < 0) {
if (p->roleFlag == 1) {                    //生产者
if (p->currentStep == 2) {printf("%20s: 无空缓冲区, 该进程被阻塞!\n", p->name);
} else if (p->currentStep == 3) {printf("%20s: 其他进程正在访问缓冲区, 该进程被阻塞!\n", p->name);
}
} else if (p->roleFlag == 0) {            //消费者
if (p->currentStep == 1) {printf("%20s: 无产品可取, 该进程被阻塞!\n", p->name);
} else if (p->currentStep == 2) {printf("%20s: 其他进程正在访问缓冲区, 该进程被阻塞!\n", p->name);
}
}
sleep(s->pcq, p->code);        //阻塞进程
}
}
void V(Seamphore *s, Process *p) {            //模拟V操作
s->value += 1;
if (p->roleFlag == 1) {                    //生产者
if (p->currentStep == 5) {printf("%20s: 释放缓冲区访问权!\n", p->name);
} else if (p->currentStep == 6) {printf("%20s: 产品已送入缓冲区,产品数量增加!\n", p->name);
}
} else if (p->roleFlag == 0) {            //消费者
if (p->currentStep == 4) {printf("%20s: 释放缓冲区访问权!\n", p->name);
} else if (p->currentStep == 5) {printf("%20s: 产品已取出,空缓冲区数量增加!\n", p->name);
}
}
if (s->value<= 0) {wakeup(s->pcq);
}
p->currentStep++;
}
void produce(Process *p) {            //模拟生产者进程
switch (p->currentStep) {case 1:                                                            //1 生产产品
p->data = rand()%1000;
printf("%20s: 生产一个产品%d!\n", p->name, p->data);
p->currentStep++;
break;
case 2:                                                            //2 申请空缓冲区
P(&empty, p);
break;
case 3:                                                            //3 申请访问缓冲区
P(&mutex, p);
break;
case 4:                                                            //4 将产品送入缓冲区
push(p->data);
printf("%20s: 将产品%d正送入缓冲区!\n", p->name, p->data);
p->currentStep++;
break;
case 5:                                                            //5 释放缓冲区访问权
V(&mutex, p);
break;
case 6:                                                            //6 产品已送入缓冲区,产品数量加1
V(&full, p);
p->currentStep = 1;
break;
}
}
void consume(Process *p) {                //模拟消费者进程
switch (p->currentStep) {case 1:                                                            //1 申请从缓冲区取出产品
P(&full, p);
break;
case 2:                                                            //2 申请访问缓冲区
P(&mutex, p);
break;
case 3:                                                            //3 从缓冲区中取出产品
p->data = pop();
printf("%20s: 从缓冲区中正取出产品%d!\n", p->name, p->data);
p->currentStep++;
break;
case 4:                                                            //4 释放缓冲区访问权
V(&mutex, p);
break;
case 5:                                                    //5 已从缓冲区取出一个产品,空缓冲区数量加1
V(&empty, p);
break;
case 6:                                                            //6 消费产品
printf("%20s: 消费产品%d!\n", p->name, p->data);
p->currentStep = 1;
break;
}
}
void rr() {            //模拟进程调度
Process *p;
while(1) {p = &process[rand()%processNum];        //随机选取进程集合内某一进程
if (!p->currentState) {                    //选取的进程若为阻塞态,重新选取其它可执行进程
continue;
}
if (p->roleFlag) {            //1: 生产者  0: 消费者
produce(p);
} else {consume(p);
}
Sleep(100);
}
}
void deal() {printf("\t\t生产者消费者算法模拟\n\n");
initProcess();
rr();
}
int main () {deal();
return 0;
}

C语言——生产者消费者问题相关推荐

  1. C语言生产者消费者实验报告,生产者与消费者实验报告.doc

    生产者与消费者实验报告.doc 生产者和消费者实验报告[实验目的]1. 加深对进程概念的理解,明确进程和程序的区别.2. 进一步认识并发执行的实质.3. 验证用信号量机制实现进程互斥的方法.4. 验证 ...

  2. windows进程生产者消费者代码c语言,生产者消费者问题---C语言实现

    生产者消费者问题(Producer-consumer problem) 是一个多线程同步问题的经典案例. 生产者的主要作用是生成一定量的数据放到缓冲区中,然后重复此过程.与此同时,消费者也在缓冲区消耗 ...

  3. C语言 生产者消费者模型

    友链 互斥量mutex 条件变量cond gcc 1.c -o 1 -lpthread // ..使用内存映射可以拷贝文件 /* 对原始文件进行内存映射 创建一个新文件 把新文件的数据拷贝映射到内存中 ...

  4. 实现一个通用的生产者消费者队列(c语言版本)

    背景:笔者之前一直从事嵌入式音视频相关的开发工作,对于音视频的数据的处理,生产者消费者队列必不可少,而如何实现一个高效稳定的生产者消费者队列则十分重要,不过按照笔者从业的经验,所看到的现象,不容乐观, ...

  5. 生产者消费者操作系统实验报告用C语言来实现

    #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <unistd.h& ...

  6. C语言实战——生产者消费者问题

    C语言实战--生产者消费者问题 方法摘要 生产者消费者共享缓冲区,生产者向缓冲区中放数据,消费者从缓冲取中取数据,当缓冲区中被放满时,生产者进程就必须进入挂起状态,直到消费者从缓冲中取走数据时,生产者 ...

  7. Linux下生产者消费者问题的C语言实现

    注:查看全文请关注作者,或点击前往:生产者-消费者问题的C语言实现 实验六 生产者-消费者问题实现 实验题目 要求 在Linux操作系统下用C实现经典同步问题:生产者-消费者,具体要求如下: (1) ...

  8. 在Linux系统下生产者消费者,生产者-消费者问题实现 (linux下C语言)

    操作系统的一个经典问题是"生产者-消费者"问题, 这涉及同步信号量和互斥信号量的应用, 在这里,我用线程的同步和互斥来实现. /* * author 张文 * 2008/06/20 ...

  9. 生产者消费者代码c语言_由生产者消费者模型引出的线程同步问题

    由生产者消费者模型引出的线程同步问题 基本生产者消费者模型: 代码示例: 数据模型: /*** Created by IntelliJ IDEA.** @Author: ZhangDong* @Dat ...

最新文章

  1. 用Select查询结果创建ACCESS表
  2. 手机版html页面左右滑动切换页面,移动端手指左右滑动切换内容demo
  3. Python编程基础:第四十五节 方法链Method Chaining
  4. 程序员面试题精选100题(63)-数组中三个只出现一次的数字[算法]
  5. CSDN博客的安全性为什么一直如此薄弱?
  6. day inset_按 SetPrinter API 修改打印机设置 - Application Developer | Microsoft Docs
  7. (转)apple-touch-icon-precomposed 和 apple-touch-icon属性区别
  8. Lambda表达式基础
  9. 太经典了,不转不行淘宝上面的对话
  10. MySQL实现跨库join查询
  11. 百度蜘蛛的工作原理,什么内容才容易被百度蜘蛛抓取?
  12. 爱普生打印机无法正常工作的解决方法
  13. el-table单元格不自动换行
  14. layer添加元素 openlayer_OpenLayers 官网例子的中文详解
  15. 插入区间之非合并区间的思路 leetcode57
  16. WARN Error while fetching metadata with correlation id 1 : {first=LEADER_NOT_AVAILABLE} (org.apache.
  17. 《微观经济学》 第五章
  18. DAPM-widget
  19. 从智造中来到智造中去,施耐德电气既是“懂行人”也是“领路人”
  20. 字符集编码(三):Unicode

热门文章

  1. 报错:TEXT must be immediately followed by END_TAG and not START_TAG (position: START_TAG seen ...<depe
  2. pytorch使用argmax argsoftmax
  3. 使用 Bitnami PostgreSQL Docker 镜像快速设置流复制集群
  4. 蛋花花:程序员入门门槛真的很低吗
  5. php header expire,解决PHP Expires 导致CDN出现TCP_MISS
  6. Android-春招-面试经历-2019年,2021年Android进阶者的新篇章
  7. ubuntu16.04 libgomp.so.1: version `GOMP_4.0‘
  8. Unity程序闪退与卡顿原因分析
  9. 20.2.25排位赛B
  10. U盘格式化后数据能恢复吗?答案在这里