生产者消费者模式 php 【转】
在工作中常常听到某某大牛之间的交谈会涉及到,xx消费者啊啥的,到底什么大牛之间讲的是什么?
这篇文章主要解决三个问题:
1.到底什么是生产者和消费者,以及它们之间的故事
2.它们之间靠什么交流
3.应用场景
正文
一、什么是生产者和消费者,以及它们之间的故事
在实际的程序开发中,会经常碰到这样的情况:小a模块负责生产数据,这些数据由另外一个模块负责处理。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。
单单抽象出生产者和消费者,还够不上是生产者/消费者模式。该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据。大概的结构如下图。
可以这么理解,你(生产者)需要写信寄给基友,你先放到邮箱(缓冲区),邮递员(消费者)从邮箱取信进行派送(数据处理)。
那么有同学问了,好好的生产者和消费者直接沟通不就好了,搞出一个缓冲区是做甚?
其实这是有内涵(优点)的:
解耦
假设生产者和消费者都是两个类,如果直接让生产者调消费者的类的方法,势必会使其依赖于消费者的类方法,万一消费者的消费方式改变(函数改掉啦)那么生产者也要改。好了,代码耦合了。
那么如果有了缓冲区就不一样了,两个都依赖于缓冲区,缓冲区只起到缓冲数据作用,一边存一边取,互不关联也不依赖。
ps:你写信直接交给邮递员,万一邮递员换了,那你不是还要重新认识一下,还要关心是不是真的邮递员。那如果是放邮箱的话,邮递员是谁和你半毛钱关系没有。
支持并发
生产者直接调消费者某个方法有个弊端:由于函数是同步的,也可以说是阻塞的,消费者没返回之前,生产者只能一直等着,万一消费者处理的又很慢,那生产者空闲着就浪费了。
使用了生产者/消费者模式之后,生产者和消费者可以是两个独立的并发主体。生产者把制造出来的数据往缓冲区一丢,就可以再去生产下一个数据。基本上不用依赖消费者的处理速度。
ps:如果没邮箱,你就要站在等邮递员来,想必这是坑爹的一件事。
支持生产消费者忙闲不均
缓冲区还有另一个好处。如果制造数据的速度时快时慢,缓冲区的好处就体现出来了。当数据制造快的时候,消费者来不及处理,未处理的数据可以暂时存在缓冲区中。等生产者的制造速度慢下来,消费者再慢慢处理掉。
ps:万一今天是情人节啥的,寄信的人特别多,邮递员一回只能带100封,那么多余100封的部分就可以放在邮箱,等处理好100封后再回头取,继续处理。
它们之间靠什么交流
那么生产者和消费者之间怎么交流呢?当然是通过数据单元交流的。何谓数据单元捏?简单地说,每次生产者放到缓冲区的,就是一个数据单元;每次消费者从缓冲区取出的,也是一个数据单元。
ps:寄信,信就是数据单元
那么数据单元涉及到一个很关键的问题,就是数据粒度的问题。
有时出于性能等因素的考虑,也可能会把N个业务对象打包成一个数据单元。那么,这个N该如何取值就是颗粒度的考虑了。颗粒度的大小是有讲究的。太大 的颗粒度可能会造成某种浪费;太小的颗粒度可能会造成性能问题。颗粒度的权衡要基于多方面的因素,以及一些经验值的考量。
ps:还是拿寄信的例子。如果颗粒度过小(比如设定为1),那邮递员每次只取出1封信。如果信件多了,那就得来回跑好多趟,浪费了时间。
如果颗粒度太大(比如设定为100),那寄信的人得等到凑满100封信才拿去放入邮筒。假如平时很少写信,就得等上很久,会很不爽滴~
应用场景
那么在php中哪些地方会用到呢,或者说哪些地方会看到别人用到生产者和消费者模式?这里简单讲几个:
swoole
对,你没看错,就是swoole。那么swoole其实是有使用了这个设计的模式,业务逻辑(生产者)将数据单元通过swoole的send函数弄到swoole的一个缓冲区之间,通过work进程进行分发,task进程(消费者)进行消费。
耗时操作的异步处理
当“耗时操作“遇到了”高并发“,如果不采取一点措施,卡慢崩会慢慢到来,此时可以将要处理的耗时操作的相关信息(数据单元)通过业务逻辑[生产者]push到redis队列中(redis只是举例),在通过跑一个脚本的进程[消费者]进行pop出数据单元进行处理。
转载自
http://blog.csdn.net/u011957758/article/details/51138707
生产者消费者模式 php 【转】的更多相关文章
- java多线程 生产者消费者模式
package de.bvb; /** * 生产者消费者模式 * 通过 wait() 和 notify() 通信方法实现 * */ public class Test1 { public static ...
- LabVIEW之生产者/消费者模式--队列操作 彭会锋
LabVIEW之生产者/消费者模式--队列操作 彭会锋 本文章主要是对学习LabVIEW之生产者/消费者模式的学习笔记,其中涉及到同步控制技术-队列.事件.状态机.生产者-消费者模式,这几种技术在在本 ...
- 转:Task任务调度实现生产者消费者模式 (个人理解后文)
纯属个人愚见.欢迎加入反驳(PiDou). 1.前文大致就是,利用Queue配置的一个TaskFactory任务调度器.实现生产者消费者模式的例子..首先我就试了 第一种 FIFO(先进先出)的配置. ...
- Lucene.net站内搜索—4、搜索引擎第一版技术储备(简单介绍Log4Net、生产者消费者模式)
目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...
- MVC异常日志生产者消费者模式记录(异常过滤器)
生产者消费者模式 定义自己的异常过滤器并注册 namespace Eco.Web.App.Models { public class MyExceptionAttribute : HandleErro ...
- 转:Task任务调度实现生产者消费者模式
我们经常会遇到生产者消费者模式,比如前端各种UI操作事件触发后台逻辑等.在这种典型的应用场景中,我们可能会有4个业务处理逻辑(下文以P代表生产者,C代表消费者): 1. FIFO(先进先出) ...
- .net学习之多线程、线程死锁、线程通信 生产者消费者模式、委托的简单使用、GDI(图形设计接口)常用的方法
1.多线程简单使用(1)进程是不执行代码的,执行代码的是线程,一个进程默认有一个线程(2)线程默认情况下都是前台线程,要所有的前台线程退出以后程序才会退出,进程里默认的线程我们叫做主线程或者叫做UI线 ...
- 使用BlockingQueue的生产者消费者模式
BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.使用场景. 首先它是一个队列,而一个队 ...
- Java设计模式—生产者消费者模式(阻塞队列实现)
生产者消费者模式是并发.多线程编程中经典的设计模式,生产者和消费者通过分离的执行工作解耦,简化了开发模式,生产者和消费者可以以不同的速度生产和消费数据.这篇文章我们来看看什么是生产者消费者模式,这个问 ...
- 【多线程】--生产者消费者模式--Lock版本
在JDK1.5发布后,提供了Synchronized的更优解决方案:Lock 和 Condition 我们使用这些新知识,来改进例子:[多线程]--生产者消费者模式--Synchronized版本 改 ...
随机推荐
- oracle中如何只查询一条复合条件的记录,即查到一条记录就返回(转)
可以用rownum来查询一条记录. 如emp表中有如下数据. 要求查询deptno为20的,但只取一条记录,可用如下语句: select * from emp where deptno=20 and ...
- VM虚拟机打不开,没有反应,解决方法。
最近的项目开发,需要用到虚拟机,但是打开虚拟机VM8却发现,以前创建的虚拟机都用不了,点击左侧[我的计算机]中的虚拟机列表,没有任何反应,也没有任何错误提示,服务中所有的虚拟机服务都开启了,网上百度没 ...
- zabbix疑难之时区问题
zabbix疑难总结: 1.zabbix的web界面的时间不对.晚12个小时整 适用于:安装网上的说法来修改,但是时间仍然不对的情况 我们按照以前的网上的那些方法在配置zabbix,需要配置时区: ...
- ccf-20170303--Markdown
我的想法如下图: 代码和题目如下: 问题描述 试题编号: 201703-3 试题名称: Markdown 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 Markdown 是一 ...
- 虚拟DOM与DOM diff算法
虚拟DOM是什么? 一个虚拟DOM(元素)是一个一般的js对象, 准确的说是一个对象树(倒立的) 虚拟DOM保存了真实DOM的层次关系和一些基本属性,与真实DOM一一对应,如果只是更新虚拟DOM, 页 ...
- UVA1451 Average
嘟嘟嘟 看到比值,就想到01分数规划,令\(ans = \frac{\sum a_i}{\sum l_i}\),其中\(l\)表示长度,所以\(l_i\)都是\(1\). 然后变一下型,得到\(\su ...
- 第一行代码 -3-1 软件也要拼脸蛋-UI界面
<ListView android:id="@+id/list_view" android:layout_width="match_parent" and ...
- oracle 定期迁移分区表数据(不落地)
[oracle@SJ ~]$ cat /home/oracle/JY_SJ.sh #!/bin/bashsource /home/oracle/.bash_profileSDATE=$(date + ...
- JavaScript高级程序设计学习(四)之引用类型
在javascript中也是有引用类型的,java同样如此. javascript常见也比较常用的引用类型就熟Object和Array. 一个对象和一个数组,这个在前后端分离开发中也用的最多.比如aj ...
- Kubernetes1.91(K8s)安装部署过程(八)-- kubernetes-dashboard安装
kubernets-dashboard顾名思义是操作面板安装,也就是可视化管理机器,同意我们用镜像结合配置文件部署. 1.下载镜像: docker pull registry.docker-cn.co ...