摘录python核心编程

本例中演示生产者-消费者模型:商品或服务的生产者生产商品,然后将其放到类似队列的数据结构中。生产商品中的时间是不确定的,同样消费者消费商品的时间也是不确定的。

使用queue模块(python2.x版本中,叫Queue)来提供线程间通信的机制,从而让线程之间可以分享数据。具体而言,就是创建一个队列,让生产者(线程)在其中放入新的商品,而消费者(线程)消费这些商品。

下表是queue模块的部分属性:

属性 描述
queue模块的类
Queue(maxsize=0) 创建一个先入先出队列。如果给定最大值,则在队列没有空间时阻塞;否则,为无限队列
LifoQueue(maxsize=0) 创建一个后入先出队列。如果给定最大值,则在队列没有空间时阻塞;否则,为无限序列
PriorityQueue(maxsize=0) 创建一个优先级队列。如果给定最大值,则在队列没有空间时阻塞;否则,为无限序列
queue异常
Empty 当对空队列调用get*()方法时抛出异常
Full 当对已满的队列调用put*()方法时抛出异常
queue对象方法
qsize() 返回队列大小。(由于返回队列大小时可能被其他线程修改,所以该值为近似值)
empty() 如果队列为空,则返回True,否则返回False
full() 如果队列已满,则返回True,否则返回False
put(item,block=True,timeout=None) 将item放入队列。如果block为True(默认值),且timeout为None,则在有可用空间之前阻塞;如果timeout为正值,最多阻塞timeout秒;如果block为False,则抛出Empty异常
put_nowait(item) 和put(item,False)效果相同
get(block=True,timeout=None) 从队列上取得元素。如果给定了block(非0),则一直阻塞直到有可用的元素为止
get_nowait() 和get(False)效果想用
task_done() 用于表示队列中的某个元素已执行完成,该方法会被下面的join()使用
join() 在队列中所有元素执行完毕并调用上面的task_done()信号前,保持阻塞。

下面的prodcons.py脚本中使用了queue对象实现了生产者-消费者场景,随机生产或消费商品,且生产者和消费者独立、并发的执行线程。注意,这里使用了在之前章节中改写的MyThread类

  1. #python 3.6
  2. from random import randint
  3. from time import sleep
  4. from queue import Queue
  5. from myThread import MyThread
  6. #将一个对象放入队列中
  7. def writeQ(queue):
  8. print('正在为队列生产………')
  9. queue.put('商品',1)
  10. print('当前商品总数:',queue.qsize())
  11. #消费队列中的一个对象
  12. def readQ(queue):
  13. val = queue.get(1)
  14. print('正在从队列中消费商品……消费后还剩余商品:',queue.qsize())
  15. #模仿生产者。
  16. def writer(queue,loops):
  17. for i in range(loops):
  18. writeQ(queue)
  19. sleep(randint(1,3))#writer的睡眠时间一般比reader短,是为了阻碍 reader从空队列中获取对象,换句话说就是使得轮到reader执行时,已存在可消费对象的可能性更大。
  20. #模仿消费者
  21. def reader(queue,loops):
  22. for i in range(loops):
  23. readQ(queue)
  24. sleep(randint(2,5))
  25.  
  26. funcs = [writer,reader]
  27. nfuncs = range(len(funcs))
  28.  
  29. def main():
  30. nloops = randint(2,5)#randint randrange类似,区别在于,randrange是半开半闭区间,而randint是闭区间
  31. q = Queue(32)
  32.  
  33. threads = []#模拟线程池
  34. for i in nfuncs:
  35. t = MyThread(funcs[i],(q,nloops),funcs[i].__name__)#创建线程
  36. threads.append(t)
  37.  
  38. for i in nfuncs:
  39. threads[i].start() #开始执行线程
  40.  
  41. for i in nfuncs:
  42. threads[i].join()
  43.  
  44. print('结束')
  45.  
  46. if __name__ == '__main__':
  47. main()

执行效果类似:

  1. PS C:\Users\WC> python E:\Python3.6.3\workspace\prodcons.py
  2. 开始执行 writer 在: Thu Apr 19 21:06:22 2018
  3. 正在为队列生产………
  4. 开始执行 reader 在: Thu Apr 19 21:06:22 2018
  5. 当前商品总数: 1
  6. 正在从队列中消费商品……消费后还剩余商品: 0
  7. 正在为队列生产………
  8. 当前商品总数: 1
  9. 正在从队列中消费商品……消费后还剩余商品: 0
  10. 正在为队列生产………
  11. 当前商品总数: 1
  12. 正在从队列中消费商品……消费后还剩余商品: 0
  13. 正在为队列生产………
  14. 当前商品总数: 1
  15. 正在为队列生产………
  16. 当前商品总数: 2
  17. writer 结束于: Thu Apr 19 21:06:30 2018
  18. 正在从队列中消费商品……消费后还剩余商品: 1
  19. 正在从队列中消费商品……消费后还剩余商品: 0
  20. reader 结束于: Thu Apr 19 21:06:39 2018
  21. 结束

python多线程编程-queue模块和生产者-消费者问题的更多相关文章

  1. python 多线程笔记(5)-- 生产者/消费者模式

    我们已经知道,对公共资源进行互斥访问,可以使用Lock上锁,或者使用RLock去重入锁. 但是这些都只是方便于处理简单的同步现象,我们甚至还不能很合理的去解决使用Lock锁带来的死锁问题. 要解决更复 ...

  2. python 多线程笔记(6)-- 生产者/消费者模式(续)

    用 threading.Event() 也可以实现生产者/消费者模式 (自己拍脑袋想出来的,无法知道其正确性,请大神告知为谢!) import threading import time import ...

  3. Python多线程的简单实现(生产者消费者模型)

    __author__ = "JentZhang" import time, threading, queue q = queue.Queue(maxsize=) # 声明队列 de ...

  4. python多线程编程

    Python多线程编程中常用方法: 1.join()方法:如果一个线程或者在函数执行的过程中调用另一个线程,并且希望待其完成操作后才能执行,那么在调用线程的时就可以使用被调线程的join方法join( ...

  5. day-3 python多线程编程知识点汇总

    python语言以容易入门,适合应用开发,编程简洁,第三方库多等等诸多优点,并吸引广大编程爱好者.但是也存在一个被熟知的性能瓶颈:python解释器引入GIL锁以后,多CPU场景下,也不再是并行方式运 ...

  6. python多线程与threading模块

    python多线程与_thread模块 中介绍了线程的基本概念以及_thread模块的简单示例.然而,_thread模块过于简单,使得我们无法用它来准确地控制线程,本文介绍threading模块,它提 ...

  7. Python并发编程-queue

    Python并发编程-queue 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Queue # !/usr/bin/env python # _*_conding:utf-8_ ...

  8. 关于python多线程编程中join()和setDaemon()的一点儿探究

    关于python多线程编程中join()和setDaemon()的用法,这两天我看网上的资料看得头晕脑涨也没看懂,干脆就做一个实验来看看吧. 首先是编写实验的基础代码,创建一个名为MyThread的  ...

  9. Python 单向队列Queue模块详解

    Python 单向队列Queue模块详解 单向队列Queue,先进先出 '''A multi-producer, multi-consumer queue.''' try: import thread ...

随机推荐

  1. python3 之 变量作用域详解

    作用域: 指命名空间可直接访问的python程序的文本区域,这里的 ‘可直接访问’ 意味着:对名称的引用(非限定),会尝试在命名空间中查找名称: L:local,局部作用域,即函数中定义的变量: E: ...

  2. FullGC排查心得

    最近线上系统(JDK1.7)出现了多次FullGC,但是情况都不一样,今天有时间,将FullGC的排查思路以及如何解决记录下,供大家一起探讨. 场景一: 系统发布上线之后,里面收到如下告警信息: 内容 ...

  3. P1046 陶陶摘苹果

    题目描述 陶陶家的院子里有一棵苹果树,每到秋天树上就会结出1010个苹果.苹果成熟的时候,陶陶就会跑去摘苹果.陶陶有个3030厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试. 现在 ...

  4. 【Android - IPC】之Messenger简介

    参考资料: 1.<Android开发艺术探索>第二章2.4.3 2.[Messenger完全解析] 1.Messenger概述 Messenger,译为“信使”,是Android中一种基于 ...

  5. Spring Cloud第二篇 | 使用并认识Eureka注册中心

    ​ 本文是Spring Cloud专栏的第二篇文章,了解前一篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 ​​ 一.Sprin ...

  6. linux进程间通信之共享内存学习记录

    进程 狭义定义:进程是正在运行的程序的实例(an instance of a computer program that is being executed). 广义定义:进程是一个具有一定独立功能的 ...

  7. CA-RNN论文读取

    ***CA-RNN: Using Context-Aligned Recurrent Neural Networks for Modeling Sentence Similarity(CA-RNN:使 ...

  8. 【并发技术16】线程同步工具Exchanger的使用

    如果两个线程在运行过程中需要交换彼此的信息,比如一个数据或者使用的空间,就需要用到 Exchanger 这个类,Exchanger 为线程交换信息提供了非常方便的途径,它可以作为两个线程交换对象的同步 ...

  9. MyBatis系列(一) MyBatis入门

    前言 MyBatis官方文档:https://mybatis.org/mybatis-3/zh/index.html MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由 ...

  10. luogu P1168 中位数 |树状数组+二分

    题目描述 给出一个长度为NN的非负整数序列A_i,对于所有1 ≤ k ≤ (N + 1) / 21≤k≤(N+1)/2,输出A_1, A_3, -, A_2k - 1的中位数.即前1,3,5,-个数的 ...