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版生产者与消费者模式的更多相关文章

  1. 用ReentrantLock和Condition实现生产者和消费者模式

    前面一篇文章<wait.notify应用场景(生产者-消费者模式)>是一种生产者消费者模式实现,今晚这是Lock方式实现,下面是源码: 生产者代码: /** * 生产者 * * @auth ...

  2. 【爬虫】Condition版的生产者和消费者模式

    Condition版的生产者和消费者模式 threading.Condition 在没有数据的时候处于阻塞状态,有数据可以使用notify的函数通知等等待状态的线程运作 threading.Condi ...

  3. 【爬虫】Load版的生产者和消费者模式

    ''' Lock版的生产者和消费者模式 ''' import threading import random import time gMoney = 1000 # 原始金额 gLoad = thre ...

  4. Java并发编程(4)--生产者与消费者模式介绍

    一.前言 这种模式在生活是最常见的,那么它的场景是什么样的呢? 下面是我假象的,假设有一个仓库,仓库有一个生产者和一个消费者,消费者过来消费的时候会检测仓库中是否有库存,如果没有了则等待生产,如果有就 ...

  5. 使用libuv实现生产者和消费者模式

    生产者和消费者模式(Consumer + Producer model) 用于把耗时操作(生产线程),分配给一个或者多个额外线程执行(消费线程),从而提高生产线程的响应速度(并发能力) 定义 type ...

  6. java生产者与消费者模式

    前言: 生产者和消费者模式是我们在学习多线程中很经典的一个模式,它主要分为生产者和消费者,分别是两个线程, 目录 一:生产者和消费者模式简介 二:生产者和消费者模式的实现 声明:本例来源于java经典 ...

  7. Java多线程设计模式(2)生产者与消费者模式

    1 Producer-Consumer Pattern Producer-Consumer Pattern主要就是在生产者与消费者之间建立一个“桥梁参与者”,用来解决生产者线程与消费者线程之间速度的不 ...

  8. java 线程并发(生产者、消费者模式)

    线程并发协作(生产者/消费者模式) 多线程环境下,我们经常需要多个线程的并发和协作.这个时候,就需要了解一个重要的多线程并发协作模型“生产者/消费者模式”. Ø 什么是生产者? 生产者指的是负责生产数 ...

  9. java进阶(40)--wait与notify(生产者与消费者模式)

    文档目录: 一.概念 二.wait的作用 三.notify的作用 四.生产者消费者模式 五.举例 ---------------------------------------分割线:正文------ ...

随机推荐

  1. zt 正则

    http://deerchao.net/tutorials/regex/regex.htm     正则表达式30分钟入门教程 版本:v2.3.5 (2017-6-12) 作者:deerchao 转载 ...

  2. HDU 5977 Garden of Eden

    题解: 路径统计比较容易想到点分治和dp dp的话是f[i][j]表示以i为根,取了i,颜色数状态为j的方案数 但是转移这里如果暴力转移就是$(2^k)^2$了 于是用FWT优化集合或 另外http: ...

  3. C#使用FileSystemWatcher控件实现的文件监控功能示例

    本文实例讲述了C#使用FileSystemWatcher控件实现的文件监控功能.分享给大家供大家参考,具体如下: FileSystemWatcher 可以使用FileSystemWatcher组件监视 ...

  4. SQL反模式学习笔记20 明文密码

    目标:恢复或重置密码 反模式:使用明文存储密码 1.存储密码 使用明文存储密码或者在网络上传递密码是不安全的. 如果攻击者截取到你用来插入(或者修改)密码的sql语句,就可以获得密码.     黑客获 ...

  5. CommonJs规范详解---【XUEBIG】

     CommonJS是服务器模块的规范,Node.js采用了这个规范   1.CommonJs规范的出发点:JS没有模块系统.标准库较少.缺乏包管理工具:为了让JS可以在任何地方运行,以达到Java.C ...

  6. C语言中使用bool

    声明 C语言中是没有bool类型的. 使用方法 参考: https://stackoverflow.com/q/1921539.

  7. C语言面对对象设计模式汇编

    面向对象发展到今天,已经出现了许许多多优秀的实践.方法和技术.很多的技术都能够有效的提高软件质量.IBM上的<面向对象软件开发和过程>系列文章对面对对象设计从如下层面进行了详细的介绍:代码 ...

  8. 创建phpinfo(PHP探针)查看自己服务器空间php详细信息

    创建phpinfo(PHP探针)查看自己服务器空间php详细信息 <?phpphpinfo();?> 保存,然后更改文件名为phpinfo.php 放到你域名根目录,然后访问:http:/ ...

  9. 【转】Spring总结以及在面试中的一些问题

    [转]Spring总结以及在面试中的一些问题. 1.谈谈你对spring IOC和DI的理解,它们有什么区别? IoC Inverse of Control 反转控制的概念,就是将原本在程序中手动创建 ...

  10. 一分钟掌握位运算符—与(&)、非(~)、或(|)、异或(^)

    第一个版本:   位运算符的计算主要用在二进制中. 实际开发中也经常会遇到需要用到这些运算符的时候,同时这些运算符也被作为基础的面试笔试题. 所以了解这些运算符对程序员来说是十分必要的. 于此,记录下 ...