队列(Queue)

在多个线程之间安全的交换数据信息,队列在多线程编程中特别有用

队列的好处:

  1. 提高双方的效率,你只需要把数据放到队列中,中间去干别的事情。
  2. 完成了程序的解耦性,两者关系依赖性没有不大。

一、队列的类型:

1、lass queue.Queue(maxsize=0)

先进先出,后进后出

import queue
q = queue.Queue()   # 生成先入先出队列实例
q.put(1)  # 先放进1,再放入2
q.put(2)
print(q.get())  # # 输出
1

2、class queue.LifoQueue(maxsize=0)

是先进后出,后进新出规则,last in fisrt out

import queue
q = queue.LifoQueue()   # 生成后入先出队列实例
q.put(1)  # 先放进1,再放入2
q.put(2)
print(q.get())  ## 输出
2

3、class queue.PriorityQueue(maxsize=0)

根据优先级来取数据。存放数据的格式  : Queue.put((priority_number,data)),priority_number越小,优先级越高,data代表存入的值

import queue
q = queue.PriorityQueue()
q.put((1, "d1"))
q.put((-1, "d2"))
q.put((6, "d3"))
print(q.get())
print(q.get())
print(q.get())#执行结果
(-1, 'd2')
(1, 'd1')
(6, 'd3')

注:maxsize代表这个队列最大能够put的长度

二、队列(Queue)的内置方法

1、exception queue.Empty
当队列中的数据为空时,就会抛出这个异常。>>> import queue
>>> q = queue.Queue()
>>> q.get(block=False)   #获取不到的时候
Traceback (most recent call last):File "<input>", line 1, in <module>File "D:\Python\Python35\lib\queue.py", line 161, in getraise Empty
queue.Empty###############################################
2、 exception queue.Full
当队列中满了以后,再放数据的话,就会抛出此异常。>>> import queue
>>> q = queue.Queue(maxsize=1)  #创建队列实例,并且设置最大值为1
>>> q.put(1)
>>> q.put(1,block=False)
Traceback (most recent call last):File "<input>", line 1, in <module>File "D:\Python\Python35\lib\queue.py", line 130, in putraise Full
queue.Full###############################################
3、Queue.qsize()
查看队列的大小>>> import queue
>>> q = queue.Queue()
>>> q.put(1)
>>> q.qsize()   #查看队列的大小
1###############################################
4、Queue.empty()
队列如果为空返回True,不为空返回False>>> import queue
>>> q = queue.Queue()
>>> q.put(1)
>>> q.empty()  #队列不为空
False
>>> q.get()
1
>>> q.empty() #队列为空
True###############################################
5、Queue.full()
队列如果满了,返回True,没有满返回False>>> import queue
>>> q = queue.Queue(maxsize=1)  #设置队列的大小为1
>>> q.full()   #队列没有满
False
>>> q.put(1)
>>> q.full()   #队列已满
True###############################################
6、Queue.put(item,block=True,timeout=None)
把数据插入队列中。block参数默认为true,timeout默认值是None。如果blcok为false的话,那么在put时候超过设定的maxsize的值,就会报full 异常。如果timeout设置值得话,说明put值得个数超过maxsize值,那么会在timeout几秒之后抛出full异常。>>> import queue
>>> q = queue.Queue(maxsize=1)  #是定队列的大小为1
>>> q.put(1)
>>> q.put(1,block=False)   #block不会阻塞,会full异常
Traceback (most recent call last):File "<input>", line 1, in <module>File "D:\Python\Python35\lib\queue.py", line 130, in putraise Full
queue.Full
>>> q.put(1,timeout=1)    #超过1秒,则会报full异常
Traceback (most recent call last):File "<input>", line 1, in <module>File "D:\Python\Python35\lib\queue.py", line 141, in putraise Full
queue.Full###############################################
7、Queue.put_nowait(item)
这个其实等同于Queue.put(item,block=False)或者是Queue.put(item,False)>>> import queue
>>> q = queue.Queue(maxsize=1)
>>> q.put(1)
>>> q.put_nowait(1)   #等同于q.put(1,block=False)
Traceback (most recent call last):File "<input>", line 1, in <module>File "D:\Python\Python35\lib\queue.py", line 184, in put_nowaitreturn self.put(item, block=False)File "D:\Python\Python35\lib\queue.py", line 130, in putraise Full
queue.Full###############################################
8、Queue.get(block=True,timeout=None)
移除并返回队列中的序列。参数block=true并且timeout=None。如果block=false的话,那么队列为空的情况下,就直接Empty异常。如果timeout有实际的值,这个时候队列为空,执行get的时候,则时隔多长时间则报出Empty的异常。>>> import queue
>>> q = queue.Queue()
>>> q.put(1)
>>> q.get()
1
>>> q.get(block=False)    #获取不到值,直接抛Empty异常
Traceback (most recent call last):File "<input>", line 1, in <module>File "D:\Python\Python35\lib\queue.py", line 161, in getraise Empty
queue.Empty
>>> q.get(timeout=1)    #设置超时时间,抛出Empty异常
Traceback (most recent call last):File "<input>", line 1, in <module>File "D:\Python\Python35\lib\queue.py", line 172, in getraise Empty
queue.Empty###############################################
9、Queue.get_nowait(item)
其实这个等同于Queue.get(block=False)或者Queue.get(False)>>> import queue
>>> q = queue.Queue()
>>> q.put(1)
>>> q.get()
1
>>> q.get_nowait()   #等同于q.get(block=False)
Traceback (most recent call last):File "<input>", line 1, in <module>File "D:\Python\Python35\lib\queue.py", line 192, in get_nowaitreturn self.get(block=False)File "D:\Python\Python35\lib\queue.py", line 161, in getraise Empty
queue.Empty###############################################
10、Queue.task_done()
get()用于获取任务,task_done()则是用来告诉队列之前获取的任务已经处理完成###############################################
11、Queue.join()
block(阻塞)直到queue(队列)被消费完毕
如果生产者生产10个包子,那么要等消费者把这个10个包子全部消费完毕,生产者才能继续往下执行。

  

生产者消费者模型

并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。

1、为什么要使用生产者和消费者模式

在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。

2、什么是生产者消费者模式

生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。

3、生成者消费者模型例子

3.1、生产者生产完毕,消费者再消费例子:

import threading
import queuedef producer():"""模拟生产者:return:"""for i in range(10):q.put("骨头 %s" % i)print("开始等待所有的骨头被取走...")q.join()  # 等待这个骨头队列被消费完毕print("所有的骨头被取完了...")def consumer(n):"""模拟消费者:return:"""while q.qsize() > 0:print("%s 取到" % n, q.get())q.task_done()  # 每去到一个骨头,便告知队列这个任务执行完了q = queue.Queue()p = threading.Thread(target=producer,)
p.start()c1 = consumer("QQ")

3.2 边生产边消费的模型例子

import time,random
import queue,threading
q = queue.Queue()def producer(name):count = 0while count < 20:time.sleep(random.randrange(3))q.put(count)  # 在队列里放包子print('Producer %s has produced %s baozi..' % (name, count))count += 1def consumer(name):count = 0while count < 20:time.sleep(random.randrange(4))if not q.empty():  # 如果还有包子data = q.get()  # 就继续获取保证print(data)print('\033[32;1mConsumer %s has eat %s baozi...\033[0m' % (name, data))else:print("-----no baozi anymore----")count += 1p1 = threading.Thread(target=producer, args=('A',))
c1 = threading.Thread(target=consumer, args=('B',))
p1.start()
c1.start()

3.3、流程图

图解:

  1. 生产者生产,消费者消费。
  2. 消费者每消费一次,都要去执行以下task_done()方法,来告诉消费者已经消费成功,相当于吃完饭,消费者应该给钱了。
  3. 消费者每消费一次,则队列中计数器会做减1操作。
  4. 当队列中的计数器为0的时候,则生产者不阻塞,继续执行,不为0的时候,则阻塞,直到消费者消费完毕为止。

转载于:https://www.cnblogs.com/Keep-Ambition/p/7597664.html

【python】-- 队列(Queue)、生产者消费者模型相关推荐

  1. Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型...

    一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...

  2. 11.python并发入门(part8 基于线程队列实现生产者消费者模型)

    一.什么是生产者消费者模型? 生产者就是生产数据的线程,消费者指的就是消费数据的线程. 在多线程开发过程中,生产者的速度比消费者的速度快,那么生产者就必须等待消费者把数据处理完,生产者才会产生新的数据 ...

  3. [Linux]生产者消费者模型(基于BlockQueue的生产者消费者模型 | 基于环形队列的生产者消费者模型 | 信号量 )

    文章目录 生产者消费者模型 函数调用角度理解生产者消费者模型 生活角度理解生产者消费者模型 为什么要使用生产者消费者模型 生产者消费者模型优点 321原则 基于BlockingQueue的生产者消费者 ...

  4. 队列、生产者消费者模型

    目录 队列.生产者消费者模型.初识线程 一.用进程锁来优化抢票小程序 1.1 进程锁 1.2 优化抢票小程序 二.队列 2.1 队列的介绍 2.2 创建队列的类 2.3 使用队列的案例 三.生产者消费 ...

  5. python多线程实现生产者消费者_用Python实现多线程“生产者-消费者”模型的简单例子...

    用 Python 实现多线程"生产者 - 消费者"模型的简单例子 生产者消费者问题是一个著名的线程同步问题, 该问题描述如下: 有一个生产者在生产产品, 这些产品将提供给若干个消费 ...

  6. python进程实现生产者消费者模型

    代码展示 from multiprocessing import Process, Queue import timedef producer(q, name, food, shi):count = ...

  7. python二十三:生产者 消费者模型

    # yield 相当于return,控制的返回值 # res = yield 的另外一个特性,接收send传过来的值,赋值给res def yieldTest():print("刘备&quo ...

  8. python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))...

    昨日内容回顾 python中启动子进程 并发编程 并发 :多段程序看起来是同时运行的 ftp 网盘 不支持并发 socketserver 多进程 并发 异步 两个进程 分别做不同的事情 创建新进程 j ...

  9. python生产教程_python入门教程12-09 (python语法入门之生产者消费者模型)

    Python中的生产者消费者模型,在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题,是本章的重点内容,下面我们一起来看看吧. 生产者消费者模型 在并发编程中使用生产者和消费者模式能够解决绝大 ...

  10. 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)...

    参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...

最新文章

  1. [Z]谷歌(Google)算法面试题
  2. Oracle: SQL组合不同字段作为一个查询条件
  3. 在android C/C++ native编程(ndk)中使用logcat
  4. 中小企业 软交换机 呼叫中心 需要的请留言
  5. Python之max(num, key=lambda x:x[0])用法的详细解析
  6. mac无法访问samba共享 提示输入用户名密码
  7. 渲染性能测试 , 结果比想象中好很多.
  8. 两个数组结果相减_学点算法(三)——数组归并排序
  9. MySQL笔记-Windows安装MySQL5.7
  10. Struts2 之 对xwork的理解
  11. dta乱码_DTA是自动化索引的出色工具
  12. linux service和daemon
  13. C3P0连接池配置文档
  14. Axure原型图(以微信作为参考)
  15. MyBatis Mapper.xml的choose/case标签详解
  16. Java-茴香豆研究(一)
  17. 如何让vnc控制由默认的twm界面改为gnome?(转)
  18. 第二十三讲 常用技术标准【2021年软考-高级信息系统项目管理师】
  19. ninja 编译threadx(ubuntu)
  20. 曙光服务器虚拟软驱,曙光IPMI系统管理平台用户使用指南(一).pdf

热门文章

  1. JavaScrip节点属性-访问子节点
  2. 阅读《构建执法》11-12章
  3. 在PHP中开启CURL扩展,使其支持curl()函数
  4. 逐步完善自己的3D引擎
  5. JAVA基础-XML的解析
  6. 第六章-深入理解类(一)
  7. Java continue的关键字
  8. DFS+剪枝:N个蛋放入M个篮子并可以任意取
  9. 几个北大和南开学霸的公众号,值得学习
  10. 地震预警,生死十秒,我们能做些什么?