• 生产者消费者模式 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

  • 相关阅读:
    Sql Server 日期推算处理,格式化处理
    自动升级功能(zt)
    绘制普通的可上下左右布局的RULER(zt)
    合并两个WORD文档,并且修改Word中标签的内容
    Sql Server 中汉字处理排序规则,全角半角
    用函数式编程技术编写优美的 JavaScript(zt)
    什么是序列化?
    日期概念理解中的一些测试
    DataSet,DataTable 不使用EXCEL组件直接保存为EXCEL
    接口测试自动化实践指南
  • 原文地址:https://www.cnblogs.com/clphp/p/7941290.html
Copyright © 2020-2023  润新知