实验要求:

在同一个进程地址空间内执行的两个或者多个进程。生产者和消费者使用N 个不同的缓冲区。

生产者进程生产物品,然后将物品放置在一个空缓冲区中供消费者进程消费。

消费者进程从缓冲区中获得物品,然后释放缓冲区。

生产者进程生产物品时,若无空缓冲区可用,

生产者进程必须等待消费者进程释放出一个空缓冲区;

消费者进程消费物品时,

若缓冲区为空,消费者进程将被阻塞,直到新的物品被生产出来。

使用三个信号量:

一个用以阻止生产者进程和消费者进程同时操作缓冲区列表 的互斥信号量,sem_t mutex

一个当生产者进程生产出一个物品时可以用它向消费者进程发出信号的信号量sem_t full

一个消费者进程释放出一个空缓冲区时可以用它向生产者进程发出信号的信号量sem_t empty

实验步骤:

互斥信号量值的描述:

初值为1,取值范围为(-1,0,1)。

当 mutex=1 时,表示两个进程皆未进入需要互斥的临界区;

当 mutex=0 时,表示有一个进程进入临界区运行,另外一个必须等待,改入阻塞队列;

当 mutex=-1时,表示有一个进程正在临界区运行,另一个进程因等待而阻塞在信号量队列中,需要被当前已在临界区运行的进程退出时唤醒

初始数据定义:

#define p_num 6              //生产者的数量

#define c_num 5               //消费者的数量

#define M 4                //缓冲区的数量

int t1=2;              //生产者每t1 秒生产产品

int t2=1;              //消费者每t2 秒消费产品

sem_t mutex;                    //作为互斥信号量,初值设为1

sem_t full;                  //已用缓冲区数量,初值设为0

sem_t empty;                    //现有剩余缓存区,初值设为M

int buffer[M];                 //缓冲区

int pcount=20;                  //生产产品的总数量,作为计数器,的那个==0时,生产完毕结束所有生产者线程

int ccount=20;

int in=0;               //生产者生产位置

int out=0;

先生成p_num个生产者线程、c_num个消费者线程

通过生成随机数作为值,mutex+1通过生产者线程输入到循环队列B中,

此时此时进行V操作 ,full+1,empty-1;

当队列B满,生产者线程进入阻塞状态等待消费者进程取出产品, P 操作 full-1,empty+1;

反复执行下去直到线程终止。

注意:sem_wait(empty)必须要在互斥信号量关闭之前

实验代码:

#include<stdio.h>

#include<semaphore.h>

#include <pthread.h>

#include <unistd.h>

#include <stdlib.h>

#include<time.h>

#include<stdbool.h>

#define p_num 6              //生产者的数量

#define c_num 5               //消费者的数量

#define M 4                //缓冲区的数量

int t1=2;              //生产者每t1 秒生产产品

int t2=1;              //消费者每t2 秒消费产品

sem_t mutex;                    //作为互斥信号量,初值设为1

sem_t full;                  //已用缓冲区数量,初值设为0

sem_t empty;                    //现有剩余缓存区,初值设为M

int buffer[M];                 //缓冲区

int pcount=10;                  //生产产品的总数量,作为计数器,的那个==0时,生产完毕结束所有生产者线程

int ccount=20;

int in=0;               //生产者生产位置

int out=0;                   //消费者消费位置

void *producer(void* arg)

{

srand(time(NULL));

int num=*((int*)arg);

while(1)

{

if(pcount==0) break;

else

{

pcount--;

sem_wait(&empty);

sem_wait(&mutex);

buffer[in]=rand()%100;

printf("生产者 %d 将生产的产品 “%d” 放入缓冲区 %d\n",num+1,buffer[in],in);

in=(in+1)%M;

sem_post(&full);

sem_post(&mutex);sleep(t1);

}

}

}

void *customer(void* arg)

{

int num=*((int*)arg);

while(1)

{

if(ccount==0) break;

else

{

ccount--;

sem_wait(&full);

sem_wait(&mutex);

printf("消费者 %d 将缓存区 %d 中的产品 “%d” 拿出\n",num+1,out,buffer[out]);

out=(out+1)%M;

sem_post(&empty);

sem_post(&mutex);sleep(t2);

}

}

}

void main()

{

pthread_t producer_pthread[p_num],consumer_pthread[c_num];

int num1[p_num],num2[c_num];

sem_init(&mutex,0,1);

sem_init(&empty,0,M);

sem_init(&full,0,0);

printf("生产产品的总数量:%d个\n",pcount);

printf("生产者数量:%d个\n",p_num);

printf("消费者数量:%d个\n",c_num);

printf("缓存区数量:%d个\n",M);

for(int i=0;i<p_num;i++)                 //创建N个生产者线程

{

num1[i]=i;                         //编号

pthread_create(&producer_pthread[i],NULL,producer,(void*)&num1[i]);

}

for(int i=0;i<c_num;i++)                  //创建N个消费者线程

{

num2[i]=i;

pthread_create(&consumer_pthread[i],NULL,customer,(void*)&num2[i]);

}

for(int i=0;i<p_num;i++)

{pthread_join(producer_pthread[i],NULL);}

for(int i=0;i<c_num;i++)

{pthread_join(consumer_pthread[i],NULL);}

sem_destroy(&mutex);

sem_destroy(&full);

sem_destroy(&empty);

}

结果截图:

Linux 系统下用C进行进程管理(生产者-消费者问题)相关推荐

  1. linux启用ipmi服务,使用 ipmitool 实现 Linux 系统下对服务器的 ipmi 管理

    简介: IPMI 是一种可扩展的标准,它定义了如何监控硬件和传感器.控制系统部件以及记录重大事件,随着 ipmi 技术在服务器中的应用,利用 ipmi 的众多优势就成为服务器管理特别是集群管理中不可缺 ...

  2. 【Linux环境】Linux系统下如何关闭Java进程

    一.前言 Linux系统下如何kill掉一个后台Java进程,相信童鞋们都知道如何操作.首先使用ps命令查找该Java进程的进程ID,然后使用kill命令进行杀掉.具体分为两步: ps查进程ID ki ...

  3. 使用 ipmitool 实现 Linux 系统下对服务器的BMC管理

    IPMI是智能型平台管理接口(Intelligent Platform Management Interface)的缩写,是管理基于 Intel结构的企业系统中所使用的外围设备采用的一种工业标准,该标 ...

  4. Linux 系统应用编程——多线程经典问题(生产者-消费者)

    "生产者--消费者"问题是Linux多线程编程中的经典问题,主要是利用信号量处理线程间的同步和互斥问题. "生产者--消费者"问题描述如下: 有一个有限缓冲区( ...

  5. Linux系统下文件与目录权限管理

    Linux文件目录权限管理 一.Linux文件属性及权限 1.Linux文件及目录权限及属性说明 (1)权限及属性说明 (2)文件权限说明 三种权限说明:r 读  read w 写  write x ...

  6. Linux系统下使用Nco进行Netcdf管理

    Nco使用 author:forlevin date : 2020-04-15 1.安装部署Nco 当前环境:Centos7 yum源安装: 1.更新yum,避免由此导致的安装nco失败的问题,此期间 ...

  7. Linux系统下程序异常如何优雅的退出

    当我们想强制结束一个程序的时候,我们通常会给它发送一个信号然后该进程捕捉到信号,再然后该进程执行一定操作最终被终止.信号是UNIX和Linux系统响应某些条件而产生的一个事件,接收到该信号的进程会相应 ...

  8. Linux系统下进程的概念《一》

     个人主页:欢迎大家光临-->沙漠下的胡杨   各位大帅哥,大漂亮  如果觉得文章对自己有帮助  可以一键三连支持博主  你的每一分关心都是我坚持的动力   ☄: 本期重点:Linux下的进程的 ...

  9. 在Linux系统下实现进程,Linux进程学习(一)之Linux进程的基本知识和实现

    最近一周学习了Linux 进程编程的知识,现对其总结如下. 在第一部分中我们先对进程的基本概念以及在Linux 中是如何来现实进程的进行介绍 Tiger-John说明 : 许多人在学习中只注重如何编程 ...

最新文章

  1. python yaml用法详解
  2. The Hadoop Distributed Filesystem
  3. 在ASP.NET MVC5中使用特性路由
  4. 三相全桥整流电路_三相桥式全控整流电路
  5. 【POJ - 3321】 Apple Tree(dfs序 + 线段树维护 或 dfs序 + 树状数组维护)
  6. 产品面试题:朋友圈内容为何不支持直接修改?
  7. sql脚本导入sql_学习SQL:SQL脚本
  8. R语言-plyr包中的函数
  9. python下载电影包_我是如何使用python控制迅雷自动下载电影的?
  10. 储能补贴有望出台?钱从哪来还是个问题
  11. 智能系统的信息处理原理
  12. 各种转码(bytes、string、base64、numpy array、io、BufferedReader )
  13. 机械制图及计算机绘图试题库,机械制图及计算机绘图--试题库2016版.pdf
  14. Google APIs 学习/使用
  15. tableSizeFor的理解
  16. 扬帆际海:如何成为一个合格的跨境电商运营?
  17. 人工智能工程师一般需要学什么?
  18. 基于加权对立和贪婪搜索多模态工程问题的黑猩猩优化算法(Matlab代码实现)
  19. virt-install 使用说明
  20. wireshark分析实战

热门文章

  1. Spring boot 集成rocketMQ 官方文档
  2. JVM即时编译(JIT)
  3. 北京拟设数字货币试验区,“信用卡还款”场景开始测试
  4. 跟《第五人格》主美学“细分法”风格化设计
  5. 分析Java堆:内存溢出的原因
  6. C语言老鼠走迷宫(单路径)算法详细讲解
  7. 五子棋(人机对弈)——Java权值法五子棋博弈
  8. JQuery Ajax局部刷新功能
  9. LaTeX插入矩阵、表格、带斜线表头的表格、图片、超链接
  10. 用计算机画画单元计划,人教版小学信息技术(三起)三年级上册第二单元《用“画图”画画》教案(附目录)...