当前位置: 首页 > news >正文

认识生产者和消费者模式

认识生产者和消费者模式

生产者和消费者是多线程中很常见的一个问题。产生数据的模块儿,我们称之为生产者,而处理数据的模块,就称为消费者。但是单单只有生产者和消费者显然还是不够的,一般来说,我们还有一个缓冲区,抽象出来的流程如下图所示。

将这个过程以实际例子来说明:

假如我们是一个生产辣条的厂家,我们生产出来的辣条肯定是一箱一箱地放在仓库里面,然后卖出去给消费者。【不再考虑经销商环节】

1.我们把一箱一箱的辣条生产好。——>>>相当于生产者制造数据

2.我们把辣条放到仓库中。——>>>相当于将数据放到缓冲区

3.我们把辣条给取出来。——>>>相当于把数据从缓冲区取出

4.我们把取出的辣条卖给消费者吃掉。——>>>相当于从缓冲区出来的数据经过了处理

应用于爬虫

生产者:不断产生待爬取的url。【比如需要下载图片,此时就需要不断获取图片的url】

缓冲区:将获取到的url进行储存。

消费者:对生产者获取到的url从缓冲区拿出来,然后发起请求。【相当于对下载url】

对于通用爬虫(单线程)来说,我们拿到一个图片的url,然后就进行下载,效率太低。

对于异步爬虫(多线程)来说,我们可以同时从缓冲区取出多个图片的url,然后一次多张下载。

Queue队列线程安全

当采用多线程的生产者和消费者模式时,生产者生产出来的数据【对应于爬虫爬取到的图片url】,将其储存于缓冲区,【缓冲区即全局变量】,此时必然面临一个问题,就是数据不同步【数据错乱】等问题,后续再执行操作就存在一定问题了。

再举个例子:

比如有一个列表为A=[0],此时去修改里面的值,修改实际上分为两步:第一步是选取到那个元素,第二步才是赋值修改。如果说是多线程来执行这个操作,就有可能会发生一些意想不到的错误。比如第一个线程要赋值为1,第二个线程要赋值为2。按照我们正常的理解,最终结果应该是2,但是对于多线程来说,它的结果也有可能是1.

考虑这一种情况,当线程1选定了A[0],此时切换到了线程2,然后线程2选定了A[0],并且执行了下一步赋值的操作,这样就先将A这个列表赋值为2了,接着再次切换到了线程1,此时线程1完成赋值(因为在前面已经选定),此时最终结果变为1。所以多线程总是会面临各种数据不安全的问题。

解决方案:

1.加锁机制(已经讲过)

2.Queue队列线程安全。


什么是Queue队列线程安全?

类似列表,但又不是列表。

在Python中提供了同步的、线程安全的队列类,这些队列都实现了锁原语,能够在多线程中直接使用。可以使用队列来实现线程间的同步,即保证数据不会乱掉。

         

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 大型企业局域网安全解决方案
  • 如何理解内网和外网?
  • Netlogon 5774 5575 5781错误
  • 电脑网络之IP篇
  • MSExchangeAL 8144
  • 动态网页数据抓取
  • Selenium环境的配置
  • MSExchangeAL 8331
  • 老铁,了解一下Python吗?
  • Application Error 1000
  • 光学文字识别(OCR)
  • Microsoft Exchange Server 1000
  • 三、基础查询——MySQL数据库之查看列(1)
  • 应用程序池 'DefaultAppPool' 的模板永久性缓存初始化失败 | Active Server Pages 5
  • 5.MySQL数据库之排序检索数据
  • 2017-09-12 前端日报
  • AngularJS指令开发(1)——参数详解
  • HTTP那些事
  • Intervention/image 图片处理扩展包的安装和使用
  • iOS编译提示和导航提示
  • Netty 框架总结「ChannelHandler 及 EventLoop」
  • nodejs:开发并发布一个nodejs包
  • redis学习笔记(三):列表、集合、有序集合
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 分享一份非常强势的Android面试题
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 看域名解析域名安全对SEO的影响
  • 每天一个设计模式之命令模式
  • 前端攻城师
  • 前言-如何学习区块链
  • 体验javascript之美-第五课 匿名函数自执行和闭包是一回事儿吗?
  • 推荐一个React的管理后台框架
  • 好程序员大数据教程Hadoop全分布安装(非HA)
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • ​Spring Boot 分片上传文件
  • ###C语言程序设计-----C语言学习(3)#
  • #Lua:Lua调用C++生成的DLL库
  • (Charles)如何抓取手机http的报文
  • (C语言)二分查找 超详细
  • (k8s)Kubernetes 从0到1容器编排之旅
  • (笔试题)分解质因式
  • (待修改)PyG安装步骤
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (含笔试题)深度解析数据在内存中的存储
  • (接上一篇)前端弄一个变量实现点击次数在前端页面实时更新
  • (十六)视图变换 正交投影 透视投影
  • (四)Android布局类型(线性布局LinearLayout)
  • (五)网络优化与超参数选择--九五小庞
  • *算法训练(leetcode)第四十七天 | 并查集理论基础、107. 寻找存在的路径
  • ../depcomp: line 571: exec: g++: not found
  • .L0CK3D来袭:如何保护您的数据免受致命攻击
  • .MSSQLSERVER 导入导出 命令集--堪称经典,值得借鉴!
  • .net 程序发生了一个不可捕获的异常
  • .sh
  • @ComponentScan比较