队列(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 get
raise 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 put
raise 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 put
raise 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 put
raise 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_nowait
return self.put(item, block=False)
File "D:\Python\Python35\lib\queue.py", line 130, in put
raise 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 get
raise 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 get
raise 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_nowait
return self.get(block=False)
File "D:\Python\Python35\lib\queue.py", line 161, in get
raise 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 queue def 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 = 0 while count < 20:
time.sleep(random.randrange(3))
q.put(count) # 在队列里放包子
print('Producer %s has produced %s baozi..' % (name, count))
count += 1 def consumer(name):
count = 0
while 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 += 1 p1 = 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的时候,则阻塞,直到消费者消费完毕为止。

【python】-- 队列(Queue)、生产者消费者模型的更多相关文章

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

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

  2. [并发编程 - socketserver模块实现并发、[进程查看父子进程pid、僵尸进程、孤儿进程、守护进程、互斥锁、队列、生产者消费者模型]

    [并发编程 - socketserver模块实现并发.[进程查看父子进程pid.僵尸进程.孤儿进程.守护进程.互斥锁.队列.生产者消费者模型] socketserver模块实现并发 基于tcp的套接字 ...

  3. 进击的Python【第九章】:paramiko模块、线程与进程、各种线程锁、queue队列、生产者消费者模型

    一.paramiko模块 他是什么东西? paramiko模块是用python语言写的一个模块,遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接. 先来个实例: import param ...

  4. python并发编程-进程间通信-Queue队列使用-生产者消费者模型-线程理论-创建及对象属性方法-线程互斥锁-守护线程-02

    目录 进程补充 进程通信前言 Queue队列的基本使用 通过Queue队列实现进程间通信(IPC机制) 生产者消费者模型 以做包子买包子为例实现当包子卖完了停止消费行为 线程 什么是线程 为什么要有线 ...

  5. python 进程锁 生产者消费者模型 队列 (进程其他方法,守护进程,数据共享,进程隔离验证)

    #######################总结######### 主要理解 锁      生产者消费者模型 解耦用的   队列 共享资源的时候 是不安全的 所以用到后面的锁 守护进程:p.daem ...

  6. 8.12 day31 进程间通信 Queue队列使用 生产者消费者模型 线程理论 创建及对象属性方法 线程互斥锁 守护线程

    进程补充 进程通信 要想实现进程间通信,可以用管道或者队列 队列比管道更好用(队列自带管道和锁) 管道和队列的共同特点:数据只有一份,取完就没了 无法重复获取用一份数据 队列特点:先进先出 堆栈特点: ...

  7. python_way ,day11 线程,怎么写一个多线程?,队列,生产者消费者模型,线程锁,缓存(memcache,redis)

    python11 1.多线程原理 2.怎么写一个多线程? 3.队列 4.生产者消费者模型 5.线程锁 6.缓存 memcache redis 多线程原理 def f1(arg) print(arg) ...

  8. 进程,线程,GIL,Python多线程,生产者消费者模型都是什么鬼

    1. 操作系统基本知识,进程,线程 CPU是计算机的核心,承担了所有的计算任务: 操作系统是计算机的管理者,它负责任务的调度.资源的分配和管理,统领整个计算机硬件:那么操作系统是如何进行任务调度的呢? ...

  9. Python3学习之路~9.4 队列、生产者消费者模型

    一 队列queue 当必须在多个线程之间安全地交换信息时,队列在线程编程中特别有用. 队列的作用:1.解耦,使程序直接实现松耦合 2.提高处理效率 列表与队列都是有顺序的,但是他们之间有一个很大的区别 ...

  10. 03:进程Queue --- 生产者消费者模型

    1 进程Queue介绍 1 进程间数据隔离,两个进程进行通信,借助于Queue​2 进程间通信:IPC -借助于Queue实现进程间通信    -借助于文件        -借助于数据库    -借助 ...

随机推荐

  1. python langid实现语种识别

    2017-04-26 语料数据入库时有个小需求,需要用一个字段存储语料的语种,偶然发现langid可以实现这一功能,再次感叹python的好用! #coding=utf-8 import langid ...

  2. Android学习(十六) 通过GestureOverlayView进行手势识别

    一.使用GestureOverlayView进行手势识别: 1.使用Gestures Builder生成手势文件,Gestures Builder为SDK中的示例项目,使用new-->Other ...

  3. 使用ByteRef加速String类型DocValues的载入

    眼下商户索引DocValues很大,warmup时花费70-80秒(在beta环境),有62秒在载入DocValues,发现当中有54秒时间在载入string docvalues,string doc ...

  4. 程序猿的量化交易之路(24)--Cointrader之RemoteEvent远程事件实体(11)

    转载需注明出处:http://blog.csdn.net/minimicall,http://cloudtrader.top/ 在量化交易系统中.有些事件是远端传来的,比方股票的价格数据等.所以,在这 ...

  5. 摘录 LDAP

    1.LDAP就是 light DAP, 轻量级目录访问协议     LDAP是轻量目录访问协议(Lightweight Directory Access Protocol)的缩写     LDAP标准 ...

  6. FishiGUI系统架构分析 和层次结构 二

    FishiGUI的类型 FIshiGUI属于为应用程序提供图形界面服务的框架系统.它并不直接与终于用户交互(负责与终于用户交互的是在FishiGUI基础上开发的应用程序).而是接受操作系统传来的硬件消 ...

  7. 【hadoop之翊】——windows 7使用eclipse下hadoop应用开发环境搭建

    由于一些缘故,这节内容到如今才写.事实上弄hadoop有一段时间了,能够编写一些小程序了,今天来还是来说说环境的搭建.... 说明一下:这篇文章的步骤是接上一篇的hadoop文章的:http://bl ...

  8. Atitit.业务系统的新特性 开发平台 新特性的来源总结

    Atitit.业务系统的新特性 开发平台 新特性的来源总结 1.1. 语言新特性(java c# php js python lisp c++ oc swift ruby  go dart1 1.2. ...

  9. DDD中的聚合和UML中的聚合以及组合的关系

    UML:聚合关系:成员对象是整体的一部分,但是成员对象可以脱离整体对象独立存在.如汽车(Car)与引擎(Engine).轮胎(Wheel).车灯(Light)之间的关系为聚合关系,引擎.轮胎.车灯可以 ...

  10. Junit 内部解密之二: TestResult + TestListener + Assert

    转自:http://blog.sina.com.cn/s/blog_6cf812be0100wbhw.html 之前我们看到了Test接口里面的run方法有个TestResult的参数,不错,这个类就 ...