condition版生产者与消费者模式
1.简介
在爬虫中,生产者与消费者模式是经常用到的。我能想到的比较好的办法是使用redis或者mongodb数据库构造生产者消费者模型。如果直接起线程进行构造生产者消费者模型,线程容易假死,也难以构造复杂的生产者消费者模型。这里提供的condition版其实是最基本的生产者消费者模型的改良版,为了保护数据安全依旧是要开锁进行操作,但是不会循环的一直开锁,而是一旦条件不符合,则会阻塞,直到符合运行程序的条件。但是还是太low,不过这种思路值得借鉴。
2.代码
- # -*-coding:utf8 -*-
- import threading
- # Lock版本的生产者消费者模式可以正常的运行,但是太消耗CPU资源。
- # 使用while循环的方式一直开锁解锁,很消耗资源。threading.Condition可以看作Lock的改良版
- # 还有一个更好的模式就是用threading.Condition来实现
- # threading.Condition可以在没有数据的时候处于阻塞等待状态,一旦有合适的数据了,
- # 还可以使用notify相关的函数来通知其他处于等待状态的线程。这样就可以不用做一些无用的上锁
- # 和解锁的操作,可以提高程序的性能。
- # 1.acquire:获取锁
- # 2.release:解锁
- # 3.wait:释放内部占用的锁,同时线程被挂起。可以被其他线程用notify和notify_all函数唤醒,
- # 被唤醒后会继续等待获取锁,获取锁后继续执行下面的代码
- # 4.notify:唤醒一个挂起的线程,默认是第一个等待的线程。注意:notify不会释放所占用的锁
- # 5.notify_all:通知所有正在等待的线程。notify和notify_all不会释放锁。并且需要在release之前调用
- # -*-coding:utf8 -*-
- import threading
- import random
- import time
- gMoney = 1000
- gCondition = threading.Condition()
- gTimes = 0
- gTotalTimes = 30
- class Producer(threading.Thread):
- def run(self):
- global gMoney
- global gTimes
- while True:
- money = random.randint(100, 1000)
- gCondition.acquire()
- if gTimes >= gTotalTimes:
- gCondition.release()
- break
- gMoney += money
- gTimes += 1
- print('%s生产了%s元钱,剩余%s元钱' % (threading.current_thread(), money, gMoney))
- gCondition.notify_all()
- gCondition.release()
- time.sleep(0.5)
- class Consumer(threading.Thread):
- def run(self):
- global gMoney
- while True:
- money = random.randint(100, 1000)
- gCondition.acquire()
- while gMoney < money:
- if gTimes >= gTotalTimes:
- gCondition.release()
- return
- # 当不满足条件时,直接进入阻塞,不在循环开锁,关锁的消耗资源的操作
- gCondition.wait()
- gMoney -= money
- print('%s消费了%d元钱,剩余%d元钱' % (threading.current_thread(), money, gMoney))
- gCondition.release()
- time.sleep(0.5)
- def main():
- for x in range(5):
- t = Consumer(name='消费者线程%s' % x)
- t.start()
- for x in range(2):
- t = Producer(name='生产者线程%s' % x)
- t.start()
- if __name__ == '__main__':
- main()
condition版生产者与消费者模式的更多相关文章
- 用ReentrantLock和Condition实现生产者和消费者模式
前面一篇文章<wait.notify应用场景(生产者-消费者模式)>是一种生产者消费者模式实现,今晚这是Lock方式实现,下面是源码: 生产者代码: /** * 生产者 * * @auth ...
- 【爬虫】Condition版的生产者和消费者模式
Condition版的生产者和消费者模式 threading.Condition 在没有数据的时候处于阻塞状态,有数据可以使用notify的函数通知等等待状态的线程运作 threading.Condi ...
- 【爬虫】Load版的生产者和消费者模式
''' Lock版的生产者和消费者模式 ''' import threading import random import time gMoney = 1000 # 原始金额 gLoad = thre ...
- Java并发编程(4)--生产者与消费者模式介绍
一.前言 这种模式在生活是最常见的,那么它的场景是什么样的呢? 下面是我假象的,假设有一个仓库,仓库有一个生产者和一个消费者,消费者过来消费的时候会检测仓库中是否有库存,如果没有了则等待生产,如果有就 ...
- 使用libuv实现生产者和消费者模式
生产者和消费者模式(Consumer + Producer model) 用于把耗时操作(生产线程),分配给一个或者多个额外线程执行(消费线程),从而提高生产线程的响应速度(并发能力) 定义 type ...
- java生产者与消费者模式
前言: 生产者和消费者模式是我们在学习多线程中很经典的一个模式,它主要分为生产者和消费者,分别是两个线程, 目录 一:生产者和消费者模式简介 二:生产者和消费者模式的实现 声明:本例来源于java经典 ...
- Java多线程设计模式(2)生产者与消费者模式
1 Producer-Consumer Pattern Producer-Consumer Pattern主要就是在生产者与消费者之间建立一个“桥梁参与者”,用来解决生产者线程与消费者线程之间速度的不 ...
- java 线程并发(生产者、消费者模式)
线程并发协作(生产者/消费者模式) 多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”. Ø 什么是生产者? 生产者指的是负责生产数 ...
- java进阶(40)--wait与notify(生产者与消费者模式)
文档目录: 一.概念 二.wait的作用 三.notify的作用 四.生产者消费者模式 五.举例 ---------------------------------------分割线:正文------ ...
随机推荐
- MQTT服务器的搭建(Windows平台)
人工智能.智能家居越来越火,在服务器和多个终端进行通信的过程中使用传统的请求/回答(Request/Response)模式已经过时,伴随而来的是发布/订阅(Publish/Subscribe)模式-- ...
- SQL Server 中执行Shell脚本计算本地文件的内容大小
SQL Server 数据库中除了能执行基本的SQL语句外,也可以执行Shell脚本.默认安装后,SQL中的Shell脚本的功能是关闭的,需要手动打开, 执行以下脚本即可打开该功能. -- 允许配置高 ...
- java日志规约及配置示例终极总结
目录 什么是日志 常用日志框架 日志级别详解 日志的记录时机 日志使用规约 logback 配置示例 loh4j2 配置示例 什么是日志? 简单的说,日志就是记录程序的运行轨迹,方便查找关键信息,也方 ...
- 【Codeforces】【网络流】【线段树】【扫描线】Oleg and chess (CodeForces - 793G)
题意: 给定一个n*n的矩阵,一个格子上可以放一个车.其中有q个子矩阵,且q个子矩阵互不相交或者是重叠(但边界可以衔接).这q个子矩阵所覆盖的地方都是不能够放车的.车可以越过子矩阵覆盖的地方进行攻击( ...
- (转)InFluxDB数据库使用手册
InfluxDB是一个开源的时序数据库,使用GO语言开发,特别适合用于处理和分析资源监控数据这种时序相关数据.而InfluxDB自带的各种特殊函数如求标准差,随机取样数据,统计数据变化比等,使数据统计 ...
- 【C语言程序】输出前50个素数
#include <stdio.h> #include <stdlib.h> int main(void) { ; ; ){ ; ;i<x;i++){ ...
- VS2008中 VB 报错 检索 COM 类工厂中 CLSID 为 {28E68F9A-8D75-11D1-8DC3-3C302A000000} 的组件失败,原因是出现以下错误: 80040154 没有注册类 (异常来自 HRESULT:0x80040154 (REGDB_E_CLASSNOTREG))。
Resvr32 .net中引用控件的名称 如果注册成功,问题不在出现 但是如果是在x64位的系统中,即使控件注册成功,错误依照提示,是因为大多数第三方写的COM控件,只支持32位的系统, 在VS中找到 ...
- vue_mint-ui
npm install mint-ui -S main.js import { Button } from 'mint-ui'; import "mint-ui/lib/style.css& ...
- Wireshark简单使用教程3——附视频
视频https://www.bilibili.com/video/av35763613?from=search&seid=10176480091153063668 目录 抓取干净流量包的用处所 ...
- Windows系统IntelliJ IDEA安装配置
IntelliJ IDEA安装 IntelliJ IDEA,是java编程语言开发的集成环境,业界公认的最好的Java开发IDE之一.打开IDEA官方网站https://www.jetbrains.c ...