生产者和消费者可以理解为:假设有一个仓库,仓库只有一个门,生产者每生产一件商品就要放入仓库;消费者每消耗一件商品就需要从仓库中取走一件商品;不管是生产者还是消费者,仓库每次只允许一个对象进入。因此生产者和消费者的流程:
  1. 生产者只要仓库未满就可以将生产出的商品放入其中;
  2. 消费者只要缓冲池未空就可以从仓库中取走商品;
  3. 仓库被占用时,任何进程都不能访问。

1. 相关代码

/*用线程的同步和互斥来实现"生产者-消费者"问题.*/
/*
* 多生产者多消费者多缓冲区 生产者和消费者不可同时进行
* 编译:gcc -o produce-consume produce-consume.c -lpthread
* 运行:./produce-consume
*/#include <stdio.h>
#include <stdlib.h>
//#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#include <time.h>
#define M 10 // 缓冲数目
int in = 0;   // 生产者放置产品的位置
int out = 0; // 消费者取产品的位置
int buff[M] = {0}; // 缓冲初始化为0,开始时没有产品
int buffer=0; //单缓冲
sem_t empty_sem; // 同步信号量, 当满了时阻止生产者放产品
sem_t full_sem;   // 同步信号量, 当没产品时阻止消费者消费
pthread_mutex_t mutex; // 互斥信号量, 一次只有一个线程访问缓冲int product_id = 0;   //生产者id
int consumer_id = 0; //消费者id
int product_sum=0;
int consumer_sum=0;
struct timeval start; //记录时间
struct timeval end;
unsigned long timer;
/* 打印缓冲情况 */
void print()
{int i;for(i = 0; i < M; i++)printf("%d ", buff[i]);
}
/* 生产者方法 (多缓冲)*/
void *product(void * arg)
{int id = ++product_id;int t=*(int *)arg;   //t生产者生产时间while(1){// 用sleep的数量可以调节生产和消费的速度,便于观察sleep(t);//sleep(1);     sem_wait(&empty_sem);pthread_mutex_lock(&mutex);gettimeofday(&end,NULL);   //生产开始时间in = in % M;product_sum++;timer = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;       printf("time:%ldus product_%d in %d. buffer: ", timer,id, in+1);//printf("timer = %ld us\n",timer);buff[in] = 1;  print();printf("\t%d\n",product_sum);  ++in;pthread_mutex_unlock(&mutex);sem_post(&full_sem);  }
}void *consumer(void * arg)
{int id = ++consumer_id;int t=*(int *)arg;while(1){// 用sleep的数量可以调节生产和消费的速度sleep(t); sem_wait(&full_sem);pthread_mutex_lock(&mutex);gettimeofday(&end,NULL); //消费生产时间consumer_sum++;out = out % M;    timer = 1000000 * (end.tv_sec-start.tv_sec)+ end.tv_usec-start.tv_usec;printf("time:%ldus consumer_%d in %d. buffer: ", timer,id, out+1); buff[out] = 0;print();printf("\t%d\n",consumer_sum);++out; pthread_mutex_unlock(&mutex);sem_post(&empty_sem);}
}/*配置生产者消费者参数,生产者和消费的数量以及时间*/
void config(int *N1,int *N2,int *T1,int *T2)
{*N1 = 10;*N2 = 10;*T1 = 1;*T2 = 1;
}/*选择菜单*/
void menu()
{printf("------------------------------------------------------------\n");printf("-------------------------------------------------------------\n");printf("\n");
}/*多缓冲*/
void f1(int N1,int N2,int T1,int T2,void *product,void *consumer)
{//N1,N2分别是生产者消费者数目//T1,T2分别是生产消费时间pthread_t id1[N1];pthread_t id2[N2];int i;int ret1[N1];int ret2[N2];// 初始化同步信号量int ini1 = sem_init(&empty_sem, 0, M); //信号量将被进程内的线程共享int ini2 = sem_init(&full_sem, 0, 0);  if(ini1 && ini2 != 0){printf("sem init failed \n");exit(1);} //初始化互斥信号量 int ini3 = pthread_mutex_init(&mutex, NULL);if(ini3 != 0){printf("mutex init failed \n");exit(1);} // 创建N1个生产者线程for(i = 0; i < N1; i++){ret1[i] = pthread_create(&id1[i], NULL, product,&T1);if(ret1[i] != 0){printf("product%d creation failed \n", i);exit(1);}}//创建N2个消费者线程for(i = 0; i < N2; i++){ret2[i] = pthread_create(&id2[i], NULL, consumer, &T2);if(ret2[i] != 0){printf("consumer%d creation failed \n", i);exit(1);}}//销毁线程for(i = 0; i < N1; i++){pthread_join(id1[i],NULL);}for(i = 0; i < N2; i++){pthread_join(id2[i],NULL);}exit(0);
}int main(int argc,char* argv)
{menu();int c;      //选择功能scanf("%d",&c);int N1,N2,T1,T2;config(&N1,&N2,&T1,&T2);f1(N1,N2,T1,T2,product,consumer);return 0;
}

摘抄网址:https://github.com/cighao/produce-consume/blob/master/produce-consume.c

【多线程系列】之生产者消费者问题相关推荐

  1. java多线程抽奖_java 线程池、多线程并发实战(生产者消费者模型 1 vs 10) 附案例源码...

    导读 前二天写了一篇<Java 多线程并发编程>点我直达,放国庆,在家闲着没事,继续写剩下的东西,开干! 线程池 为什么要使用线程池 例如web服务器.数据库服务器.文件服务器或邮件服务器 ...

  2. python多线程问题及生产者消费者示例

    多线程能干什么: 生产者消费者问题: 一直生产,一直消费,中间有阀值,避免供求关系不平衡,导致出现问题. #线程安全问题,要是线程同时来,听谁的 #锁:一种数据结构 队列:先进线出 栈:先进后出1.解 ...

  3. mysql服务器多线程模型_java 线程池、多线程并发实战(生产者消费者模型 1 vs 10) 附案例源码 - 陈彦斌 - 博客园...

    导读 前二天写了一篇<Java 多线程并发编程>点我直达,放国庆,在家闲着没事,继续写剩下的东西,开干! 线程池 为什么要使用线程池 例如web服务器.数据库服务器.文件服务器或邮件服务器 ...

  4. Java多线程(含生产者消费者模式详解)

    多线程 导航 多线程 1 线程.进程.多线程概述 2 创建线程 (重点) 2.1 继承Thread类(Thread类也实现了Runnable接口) 2.2 实现Runnable接口(无消息返回) 2. ...

  5. 13-多线程01 实现多线程 线程同步 生产者消费者

    1.实现多线程 1.1简单了解多线程[理解] 是指从软件或者硬件上实现多个线程并发执行的技术. 具有多线程能力的计算机因有硬件支持而能够在同一时间执行多个线程,提升性能. 1.2并发和并行[理解] 并 ...

  6. Java多线程:解决生产者/消费者模式

    什么是生产者/消费者模式 生产者消费者模型具体来讲,就是在一个系统中,存在生产者和消费者两种角色,他们通过内存缓冲区进行通信,生产者生产消费者需要的资料,消费者把资料做成产品. 具体来说就是: 生产者 ...

  7. 高并发编程-使用wait和notifyAll进行线程间的通信3_多线程下的生产者消费者模型和notifyAll

    文章目录 概述 解决办法 概述 高并发编程-线程通信_使用wait和notify进行线程间的通信2_多生产者多消费者导致程序假死原因分析 中分析了假死的原因,这里我们来看下改如何解决在多线程下出现的这 ...

  8. 多线程下的生产者消费者(一个初始值为0的变量,两个线程一个加1一个减1,轮询5轮)

    在使用Lock之前,我们使用的最多的同步方式应该是synchronized关键字来实现同步方式了.配合Object的wait().notify()系列方法可以实现等待/通知模式.Condition接口 ...

  9. java 多线程 消费者_java中的多线程的实现生产者消费者模式

    丈夫类:往银行账户里存钱,存款[0~10000)的随机数,2秒存一次 妻子类:从银行账户里取钱,取款[0~10000)的随机数,2秒取一次,如果余额不足,等到丈夫存了钱,再取 public class ...

  10. java多线程之~生产者消费者

    文章目录 一.怎样使用多线程 二.生产者消费者 一.怎样使用多线程 一般来讲我们创建多线程的方式有一下几种: 1. 实现Runnable接口 并重写其中的run方法 2. 继承Thread类,重写ru ...

最新文章

  1. CUDA8.0+VS2015+Win10开发环境搭建教程
  2. Flume Sinks官网剖析(博主推荐)
  3. 五行代码玩转GPT-2,新加坡高中生开源轻量级GPT-2“客户端”
  4. 数学图形(1.21)蚌线
  5. (二)boost库之字符串格式化
  6. C# ASP.NET B/S模式下,采用lock语法 实现多用户并发产生不重复递增单号的一种解决方法技术参考...
  7. RHEL5上Oracle9i的安装
  8. 命令+mybatis-generator插件自己主动生成Mapper映射文件
  9. Windows Phone XNAでアニメーション - ぐるぐる
  10. mysql基本命令总结
  11. C#实现TreeView向XML的绝对转换类
  12. [转载] python pandas.read_csv读取大文件
  13. 一台电脑两种jdk_同一个电脑安装两个jdk版本
  14. 支付宝和微信的支付功能如何进行测试?
  15. 【SNMP】snmp trap 介绍、安装、命令|Trap的发送与接收代码实现
  16. Gitlab:从其它项目组里导入一个项目
  17. 总结自己设计带POE的八口交换机的过程和踩坑
  18. 建立量化交易趋势跟踪策略的五个指标
  19. 基于lucene的案例开发:纵横小说简介页采集
  20. Dask核心功能介绍及与Spark的比较

热门文章

  1. IDEA调整输出字体的字体与大小
  2. Linux中的docker top命令
  3. php和html开发工具,常用的php开发工具有哪些?
  4. java 左右两边数据类型不一样_java基础语法
  5. linux订阅软件包,安装 Manjaro Linux 后必做的 6 件事 | Linux 中国
  6. 单击托盘显示菜单mfc_PhotoShop制作滚动菜单栏教程
  7. 计算机nit证书怎么学,计算机等级考试证书和NIT可以抵免自考中哪些课程?
  8. C# Combobox可输入+自动完成
  9. Kotlin入门(33)运用扩展属性
  10. Android开发笔记(一百一十五)设计工具