博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
(P15)muduo_base库源码分析:BlockinngQueue(无界缓冲区),BoundedBlockingQueue(有界缓冲区)
阅读量:4299 次
发布时间:2019-05-27

本文共 2234 字,大约阅读时间需要 7 分钟。

文章目录

1.BlockinngQueue(无界缓冲区)

  • 为了保证生产者线程和消费者线程安全访问队列,可以使用信号量和条件变量对队列进行同步。
    在这里插入图片描述
  • 使用信号量的方式(1)队列是有界的
size:队列的大小;2个信号量:semFull(size)表示初始状态队列是空的,可以生产的产品个数=size;semEmpty(0)表示初始状态队列是空的,可以消费的产品个数=0;生产者线程如何操作队列?//生产者p(semFull)//若队列不满,则可以生产产品,直到生产满了,那么p(semFull)操作就会阻塞;queue.push(x)//一旦生产了一个产品,队列就不为空了,有产品可以消费了,通知消费者线程可以消费了;v(semEmpty)//消费者//若队列中没有产品可以消费,则p(semEmpty)则会阻塞p(semEmpty)x = queue.pop()//消费完产品则会腾出一个新的空间,能容纳新的产品v(semFull)若是多线程,则需要增加mutex对队列增加保护sizesemFull(size)semEmpty(0)mutex//生产者p(semFull)lock(mutex)queue.push(x)unlock(mutex)v(semEmpty)//消费者p(semFull)lock(mutex)queue.push(x)unlock(mutex)v(semFull)

在这里插入图片描述

在这里插入图片描述

  • 使用信号量的方式(2)队列是无界的
无界的话,则不需要判断队列是否已经是满的若是多线程,则需要增加mutex对队列增加保护sizesemFull(size)semEmpty(0)mutex//生产者lock(mutex)queue.push(x)unlock(mutex)v(semEmpty)//消费者p(semFull)lock(mutex)queue.push(x)unlock(mutex)

在这里插入图片描述

  • 使用条件变量的方式(1)队列是无界的
    先理解无界,再理解有界。无界只需要判断队列是否为空,有界需要在无界判断的基础上,需要多判断一个队列是否为满(无界用了一个条件变量,有界用了2个条件变量);
无界的话,则不需要判断队列是否已经是满的若是多线程,则需要增加mutex对队列增加保护sizesemFull(size)semEmpty(0)mutexnotEmpty是条件变量//生产者lock(mutex)queue.push(x)unlock(mutex)//向消费者线程发起通知,可以消费产品了,队列不为空了notEmpty.signal()//消费者//等待条件变量,等待队列不为空,队列为空,则需要等待//不用if,防止虚假唤醒while(queue.empty()){
notEmpty.wait()//生产者一旦生产产品notEmpty.signal(),队列就不为空了,等待将被唤醒}lock(mutex)queue.push(x)unlock(mutex)

在这里插入图片描述

  • 使用条件变量的方式(2)队列是有界的
有界的话,则需要判断队列是否已经是满的sizesemFull(size)semEmpty(0)mutexnotEmpty,notFull是条件变量//生产者//队列已经满了需要等待条件满足while(queue.Full()){
notFull.wait();}lock(mutex)queue.push(x)unlock(mutex)//向消费者线程发起通知,可以消费产品了,队列不为空了notEmpty.signal()//消费者//等待条件变量,等待队列不为空,队列为空,则需要等待//不用if,防止虚假唤醒while(queue.empty()){
notEmpty.wait()//生产者一旦生产产品notEmpty.signal(),队列就不为空了,等待将被唤醒}lock(mutex)queue.push(x)unlock(mutex)//消费一个产品,意味着队列不满notFull.signal()

在这里插入图片描述

  • eg:src\15\jmuduo\muduo\base\BlockingQueue.h

  • eg测试:src\15\jmuduo\muduo\base\tests\BlockingQueue_test.cc

  • 测试:生产者添加了产品,时间片恰好切换到了消费者线程,所以造成了消费者线程先打印了。一般情况都是消费者线程后打印才对。

    在这里插入图片描述

  • eg测试:src\15\jmuduo\muduo\base\tests\BlockingQueue_bench.cc

    src\15\jmuduo\muduo\base\tests\CMakeLists.txt

  • 测试:

    在这里插入图片描述

2.BoundedBlockingQueue(有界缓冲区)

  • 类图

    在这里插入图片描述

  • 环形缓冲区circular_buffer

    头部表示读的位置,尾部表示写的位置;
    写的指针不能赶上都的指针;
    缓冲区写满了,则不应该再写了,加入1号产品被消费走了,则我才可以继续写;
    在这里插入图片描述

  • eg:src\15\jmuduo\muduo\base\tests\BoundedBlockingQueue_test.cc

  • eg测试:src\15\jmuduo\muduo\base\tests\BoundedBlockingQueue_test.cc

  • 测试:生产到20个产品就阻塞了,使得消费者得去消费产品,生产者才可以继续生产产品

    在这里插入图片描述

转载地址:http://bmiws.baihongyu.com/

你可能感兴趣的文章
通过Navicat远程连接MySQL配置
查看>>
phpstorm开发工具的设置用法
查看>>
Linux 系统挂载数据盘
查看>>
Git基础(三)--常见错误及解决方案
查看>>
Git(四) - 分支管理
查看>>
PHP Curl发送数据
查看>>
HTTP协议
查看>>
HTTPS
查看>>
git add . git add -u git add -A区别
查看>>
apache下虚拟域名配置
查看>>
session和cookie区别与联系
查看>>
PHP 实现笛卡尔积
查看>>
Laravel中的$loop
查看>>
CentOS7 重置root密码
查看>>
Centos安装Python3
查看>>
PHP批量插入
查看>>
laravel连接sql server 2008
查看>>
Laravel 操作redis的各种数据类型
查看>>
Laravel框架学习笔记之任务调度(定时任务)
查看>>
laravel 定时任务秒级执行
查看>>