python之线程queue
线程queue介绍
Queue的种类:
- FIFO:
Queue.Queue(maxsize=0)
FIFO即First in First Out,先进先出。Queue提供了一个基本的FIFO容器,使用方法很简单,maxsize是个整数,指明了队列中能存放的数据个数的上限。一旦达到上限,插入会导致阻塞,直到队列中的数据被消费掉。如果maxsize小于或者等于0,队列大小没有限制。
示例:
import queue q = queue.Queue()
q.put(1)
q.put(2)
q.put(3) print(q.get())
print(q.get())
print(q.get())
输出:
1
2
3
- LIFO
Queue.LifoQueue(maxsize=0)
LIFO即Last in First Out,后进先出。与栈的类似,使用也很简单,maxsize用法同上
示例:
import queue q = queue.LifoQueue()
q.put(1)
q.put(2)
q.put(3) print(q.get())
print(q.get())
print(q.get())
输出:
3
2
1
- priority
class Queue.PriorityQueue(maxsize=0)
构造一个优先队列。maxsize用法同上。
示例:
import queue q =queue.PriorityQueue(3) q.put((2,'aaron'))
q.put((-1,'jim'))
q.put((5,'jack')) print(q.get())
print(q.get())
print(q.get())
输出:
(-1, 'jim')
(2, 'aaron')
(5, 'jack')
基本方法:
Queue.Queue(maxsize=0) FIFO, 如果maxsize小于1就表示队列长度无限
Queue.LifoQueue(maxsize=0) LIFO, 如果maxsize小于1就表示队列长度无限
Queue.qsize() 返回队列的大小
Queue.empty() 如果队列为空,返回True,反之False
Queue.full() 如果队列满了,返回True,反之False
Queue.get([block[, timeout]]) 读队列,timeout等待时间
Queue.put(item, [block[, timeout]]) 写队列,timeout等待时间
Queue.queue.clear() 清空队列
其他:
task_done()
意味着之前入队的一个任务已经完成。由队列的消费者线程调用。每一个get()调用得到一个任务,接下来的task_done()调用告诉队列该任务已经处理完毕。
如果当前一个join()正在阻塞,它将在队列中的所有任务都处理完时恢复执行(即每一个由put()调用入队的任务都有一个对应的task_done()调用)。
join()
阻塞调用线程,直到队列中的所有任务被处理掉。
只要有数据被加入队列,未完成的任务数就会增加。当消费者线程调用task_done()(意味着有消费者取得任务并完成任务),未完成的任务数就会减少。当未完成的任务数降到0,join()解除阻塞。
生产者消费者模型
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。
为什么要使用生产者和消费者模式
在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
什么是生产者消费者模式
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
import threading
import queue def producer():
for i in range(10):
q.put("骨头 %s" % i ) print("开始等待所有的骨头被取走...")
q.join() #等待所有任务完成
print("所有的骨头被取完了...") def consumer(n): while q.qsize() >0: print("%s 取到" %n , q.get())
q.task_done() #告知这个任务执行完了 q = queue.Queue()
p = threading.Thread(target=producer,)
p.start()
c1 = consumer("李闯")
注意:
- 如果没有q.task_done()的存在,就不会通知线程队列,生产者就会一直阻塞下去。
- 如果没有q.join()的存在,生产者就不会等待消费者,它会自行结束。
- q.task_done()方法和q.join()方法的存在,实现了生产者与消费者的同步机制。
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()
这个实例,充分体现了线程队列在生产者消费者模型中,是如何解决生产者与消费者的强耦合的问题。
线程queue使用注意事项
1. 阻塞模式
import queue q = queue.Queue(10) #创建一个队列 ......
for i in range(10):
q.put('A')
time.sleep(0.5)
这是一段极其简单的代码(另有两个线程也在操作队列q),我期望每隔0.5秒写一个'A'到队列中,但总是不能如愿:间隔时间有时会远远超过0.5秒。原来,Queue.put()默认有 block = True 和 timeou 两个参数。当 block = True 时,写入是阻塞式的,阻塞时间由 timeou 确定。当队列q被(其他线程)写满后,这段代码就会阻塞,直至其他线程取走数据。Queue.put()方法加上 block=False 的参数,即可解决这个隐蔽的问题。但要注意,非阻塞方式写队列,当队列满时会抛出 exception Queue.Full 的异常。
2. 无法捕获 exception Queue.Empty 的异常
while True:
......
try:
data = q.get()
except Queue.Empty:
break
本意是用队列为空时,退出循环,但实际运行起来,却陷入了死循环。这个问题和上面有点类似:Queue.get()默认的也是阻塞方式读取数据,队列为空时,不会抛出 except Queue.Empty ,而是进入阻塞直至超时。 给get方法的参数block=False 的参数,问题迎刃而解。
python之线程queue的更多相关文章
- python开发线程:死锁和递归锁&信号量&定时器&线程queue&事件evevt
一 死锁现象与递归锁 进程也有死锁与递归锁,在进程那里忘记说了,放到这里一切说了额 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将 ...
- 孤荷凌寒自学python第四十三天python 的线程同步之Queue对象
孤荷凌寒自学python第四十三天python的线程同步之Queue对象 (完整学习过程屏幕记录视频地址在文末,手写笔记在文末) Queue对象是直接操作队列池的对象,队列中可以存放多种对象,当然也 ...
- Python 36 死锁现象和递归锁、信号量、Event事件、线程queue
一:死锁现象和递归锁 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远 ...
- Python之路(第四十五篇)线程Event事件、 条件Condition、定时器Timer、线程queue
一.事件Event Event(事件):事件处理的机制:全局定义了一个内置标志Flag,如果Flag值为 False,那么当程序执行 event.wait方法时就会阻塞,如果Flag值为True,那么 ...
- python 之 并发编程(进程池与线程池、同步异步阻塞非阻塞、线程queue)
9.11 进程池与线程池 池子使用来限制并发的任务数目,限制我们的计算机在一个自己可承受的范围内去并发地执行任务 池子内什么时候装进程:并发的任务属于计算密集型 池子内什么时候装线程:并发的任务属于I ...
- python并发编程之线程(二):死锁和递归锁&信号量&定时器&线程queue&事件evevt
一 死锁现象与递归锁 进程也有死锁与递归锁,在进程那里忘记说了,放到这里一切说了额 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将 ...
- python 并发编程 多线程 线程queue
线程queue 线程之间已经是共享数据的,为什么还使用线程queue? 线程需要自己加锁,线程queue帮我们处理好加锁的问题 有三种不同的用法 第一种方法: class queue.Queue(ma ...
- Python之网路编程之死锁,递归锁,信号量,Event事件,线程Queue
一.死锁现象与递归锁 进程也是有死锁的 所谓死锁: 是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用, 它们都将无法推进下去.此时称系统处于死锁状态或系统 ...
- Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程
Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...
随机推荐
- 1.python的一些规范
Python的一些规范 1.标识符 定义:允许作为名字的有效字符串集合 名字必须有实际意义,可读性好 首字母必须是字母或下划线(_) 剩下的字符可以是字母和数字或者下划线 大小写敏感 两种风格:con ...
- What are rules about using an underscore in a c identifier
http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identi ...
- POJ 3468A Simple Problem with Integers(线段树区间更新)
A Simple Problem with Integers Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 112228 ...
- ReentrantReadWriteLock源码分析(一)
此处源码分析,主要是基于读锁,非公平机制,JDK1.8. 问题: 1.ReentrantReadWriteLock是如何创建读锁与写锁? 2.读锁与写锁的区别是什么? 3.锁的重入次数与获取锁的线程数 ...
- POJ 1045
#include<iostream> #include<cmath> #include<iomanip> using namespace std; int main ...
- 散列表碰撞处理、开链法、HashTable散列
散列表碰撞处理.开链法.HashTable散列 /** * 散列表碰撞处理.开链法.HashTable散列. * 将数组里的元素位置,也设置为数组,当两个数据的散列在同一个位置时, * 就可以放在这个 ...
- HTTP请求头及其作用 转
HTTP请求头Header及其作用详解 下面是访问的一个URL,http://www.hzau.edu.cn的一个header,根据实例分析各部分的功能和作用. 1.Accept,浏览器端能够处理的内 ...
- Binder AIDL中自定义类型传递的源码分析
binder机制实现的IPC和共享内存的方式不同,它采取的是值拷贝的方式,即进程间传递的实体遵循Parcelable协议, Bp端负责向Parcel里写东西,Bn端负责从Parcel里读取还原,顺序是 ...
- vs2013 with update2安装记录
1.安装之后,提示update2无法安装2.按照以下方法进行修复,提示无法安装的项更多了(1项变3项了) http://jingyan.baidu.com/article/6d704a13f34d10 ...
- php 数字 的简单加解密
转载 <?php /** * 加密解密类 * 该算法仅支持加密数字.比较适用于数据库中id字段的加密解密,以及根据数字显示url的加密. * @author 深秋的竹子 * @email 812 ...