C++实现生产者消费者队列

  • 分析
  • 程序
    • 队列的类
    • 生产者逻辑
    • 消费者逻辑
    • 主函数
  • 结果分析
  • 源码地址

分析

首先,我们的生产者与消费者队列需要满足同步与互斥关系,就需要一把互斥锁,以及生产者与消费者各自的条件变量。
其次,我们可以利用C++中STL里的queue队列来进行实现,但是我们需要对push,pop进行修改,因为STL库的函数不一定能满足互斥条件。也就是不一定安全。
最后,所有资源在程序结束后一定要记得释放,否则会出现内存泄漏的风险。

程序

队列的类

/thread safe queue
class BlockQueue
{public:BlockQueue(size_t Capacity = CAPACITY){_Capacity = Capacity;pthread_mutex_init(&_Lock, NULL);pthread_cond_init(&_ConsumeCond, NULL);pthread_cond_init(&_ProductCond, NULL);}//push == Producer void Push(int& Data){pthread_mutex_lock(&_Lock);//判断队列有没有满 while(IsFull()){pthread_cond_wait(&_ProductCond,&_Lock);}_Queue.push(Data);pthread_mutex_unlock(&_Lock);pthread_cond_signal(&_ConsumeCond);}//pop == consumervoid Pop(int* Data){pthread_mutex_lock(&_Lock);//判断队列有没有空 while(_Queue.empty()){pthread_cond_wait(&_ConsumeCond, &_Lock); } *Data = _Queue.front();_Queue.pop();pthread_mutex_unlock(&_Lock);pthread_cond_signal(&_ProductCond);}~BlockQueue(){pthread_mutex_destroy(&_Lock);pthread_cond_destroy(&_ConsumeCond);pthread_cond_destroy(&_ProductCond);}
private:bool IsFull(){if(_Queue.size() == _Capacity)return true;return false;}
private:queue<int> _Queue;size_t _Capacity; // queue max capacity //互斥pthread_mutex_t _Lock;//mutex//同步 pthread_cond_t _ConsumeCond; // consume cond pthread_cond_t _ProductCond; // product _ProductCond
};

生产者逻辑

void* Producter_start(void* arg)
{BlockQueue* que = (BlockQueue*)arg;int resource = 1;while(1){que->Push(resource);resource++;printf("\n\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");printf("Producter_thread : [%p]\n",pthread_self());printf("i product resource [%d]\n",resource - 1);printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");}return NULL;}

消费者逻辑

void* Consumer_start(void* arg)
{BlockQueue* que = (BlockQueue*)arg;while(1){int Data;que->Pop(&Data);printf("\n\n######################################\n");printf("Consumer_thread :  [%p]\n", pthread_self());printf("i consume resource [%d]\n", Data);printf("######################################\n");}return NULL;
}

主函数

int main()
{BlockQueue* que = new BlockQueue();pthread_t com_tid[THREADCOUNT], pro_tid[THREADCOUNT];int ret = 0;for(int i = 0; i < THREADCOUNT; i++){ret = pthread_create(&com_tid[i],NULL,Consumer_start,(void*)que);if(ret < 0){perror("pthread_create Consumer error");return 0;}ret = pthread_create(&pro_tid[i],NULL,Producter_start,(void*)que);if(ret < 0){perror("pthread_create Producter error");}}//thread wait for(int i = 0; i < THREADCOUNT; i++){pthread_join(com_tid[i],NULL);pthread_join(pro_tid[i],NULL);}//防止内存泄漏 delete que;que = NULL;return 0;
}

结果分析


我们发现最后的结果中,有一部分生产者与消费者信息的打印好像不是那么规范,但实际上他们都是合理的访问临界资源的。

因为线程之间的抢占式执行,使得每一个线程只能拥有一个CPU资源一小会,然后就需要让出CPU资源给其他线程。然后就会出现上图所示的执行逻辑。

源码地址

https://github.com/duchenlong/linux-text/blob/master/thread/threadqueue.cpp

C++实现生产者消费者队列相关推荐

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

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

  2. deque实现生产者-消费者队列

    deque实现生产者-消费者队列 1.概述 使用python内置的list类型可以实现一个生产-消费队列功能,这个队列是先进先出.把批量的数据放到生产队列可以加快程序处理业务的速度,然后消费者可以从消 ...

  3. java 消费者 生产者 队列_用Java写一个生产者-消费者队列

    packageyunche.test.producer;importjava.util.LinkedList;importjava.util.Random;/*** @ClassName: Produ ...

  4. 【C++】多线程(链式、循环队列)实现生产者消费者模式

    生产者消费者模式:         生产者消费者问题(英语:Producer-consumer problem),也称有限缓冲问题(英语:Bounded-buffer problem),是一个多线程同 ...

  5. 基于队列的生产消费设计java_生产者-消费者设计模式

    一.生产者消费者设计模式 1.中间队列 一段内存空间,且可存取: 2.两种角色 (1)生产者:生产数据: (2)消费者:消费数据. 3.三种关系 (1)生产者与生产者的互斥关系: (2)消费者与消费者 ...

  6. 生产者消费者问题——C++ windows版 多生产者多消费者的队列实现

    最进要写一个多线程加载资源的资源管理器(ResourceManager)和多线程音频解码器(MultiThread Decoder).因为距最近一次用到多线程放下好久了,所以今天把生产者消费者问题练一 ...

  7. 进程 互斥锁、队列与管道、生产者消费者模型

    目录 1.互斥锁 2.队列与管道 3.生产者消费者模型(Queue) 4.生产者消费者模型(JoinableQueue) 1.互斥锁 首先导入Lock模块 实例化一把锁 但是每次生成子进程的时候都会重 ...

  8. 11.python并发入门(part8 基于线程队列实现生产者消费者模型)

    一.什么是生产者消费者模型? 生产者就是生产数据的线程,消费者指的就是消费数据的线程. 在多线程开发过程中,生产者的速度比消费者的速度快,那么生产者就必须等待消费者把数据处理完,生产者才会产生新的数据 ...

  9. Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例

    Java阻塞队列(BlockingQueue)实现 生产者/消费者 示例 本文由 TonySpark 翻译自 Javarevisited.转载请参见文章末尾的要求. Java.util.concurr ...

最新文章

  1. 数组中的一些常用方法总结
  2. 《软件设计师》——数据结构和算法基础
  3. linux中probe函数传递参数的寻找(下)
  4. 网站排障分析常用的命令
  5. kafka+zookeeper内外网双网卡配置(针对不同网段)
  6. 文献记录(part74)--Subspace clustering via seeking neighbors with minimum reconstruction error
  7. Z表数据EXCEL导入
  8. 前端学习(977):本地存储导读
  9. IDEA Translation插件安装及设置鼠标悬浮提示的自动翻译
  10. python oracle orm_Python ORM
  11. 云计算中的Iaas,Paas和Saas
  12. Document、HTMLDocument关系的探究
  13. k8s核心技术-Pod(镜像的拉取_重启策略_资源限制)_---K8S_Google工作笔记0022
  14. android framelayout生命周期,深入理解android view 生命周期
  15. int、String、char、Array之间的转换,这一篇够了!!!
  16. GIT 操作中 Reinitialized existing Git repository in.......解决方法?
  17. 沉默,并不代表我们无话可说
  18. REINFORCE和Reparameterization Trick
  19. Error starting child
  20. (三)Linux vi 文本编辑器,用户管理,组管理,Sudo命令,时间管理

热门文章

  1. 使用U盘代替光盘来刻录ISO镜像文件的方法
  2. 微信论坛交流小程序系统毕业设计毕设(8)毕业设计论文模板
  3. BUCK降压电路PCB布局布线
  4. ClickHouse技术分享PPT
  5. Type ‘java.util.Observable‘ does not have type parameters
  6. 电子元器件简介——三极管篇
  7. 刷题记录-NPUCTF2020(web部分)
  8. GIS开发之二维地下管线综合管理系统(Arcgis)第二节 技术架构
  9. 联发科技嵌入式_【MTK联发科技嵌入式驱动工程师面试】面试官人很好,问的问题很基础。-看准网...
  10. 载波观测值与载波观测方程