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.事件 ...
随机推荐
- (转)为什么要重写 hashcode 和 equals 方法?
作者丨hsm_computer cnblogs.com/JavaArchitect/p/10474448.html 我在面试Java初级开发的时候,经常会问:你有没有重写过hashcode方法?不少候 ...
- Bootstrap框架(二)
day58 巨幕 这是一个轻量.灵活的组件,它能延伸至整个浏览器视口来展示网站上的关键内容. Hello, world! This is a simple hero unit, a simple ju ...
- module.export与export的区别?
对于大多数node初学者而言, module.exports应该都是理解的, 但多出来一个exports获取就有些疑问了 疑问一: 既然有module.exports了为什么还要有exports? 疑 ...
- (原创)JAVA阻塞队列LinkedBlockingQueue 以及非阻塞队列ConcurrentLinkedQueue 的区别
阻塞队列:线程安全 按 FIFO(先进先出)排序元素.队列的头部 是在队列中时间最长的元素.队列的尾部 是在队列中时间最短的元素.新元素插入到队列的尾部,并且队列检索操作会获得位于队列头部的元素.链接 ...
- 【bzoj2789】 Letters 树状数组
又是一道树状数组求逆序对的题目. 这一题我们可以将第二个串中的每一个字母,与第一个串中的字母做两两匹配,令第二个串第i个字母的值id[i]为该字母与第一个串中的字母匹配到的位置. 然后考虑到所求答案为 ...
- SQL使用子查询,查找班级成绩最高分
-- 根据要求,获取班级成绩的最高分的学生-- 第一个子查询,先去各个科目的最高,再横向比较各个科目的最高,再取最高分的那个科目-- 第二个子查询,查询每个同学的最高分-- 最后,通过第一个子查询查询 ...
- Python运行MapReducer程序时所遇异常
landen@Master:~/UntarFile/hadoop-1.0.4$ bin/hadoop jar contrib/streaming/hadoop-streaming-1.0.4.jar ...
- ubuntu安装maven
1.安装maven前需要安装JDK 2.下载mavenapache-maven-3.3.9-bin.tar.gz 3.解压maven到当前目录tar -zxvf apache-maven-3.3.9- ...
- 关于mpvue和wafer2-client-sdk的 微信登录失败,请检查网络状态
关于mpvue和wafer2-client-sdk的登录使用. 错误形式: <script> // import {get} from './util' import qcloud fro ...
- Android 开发工具类 16_NotificationActivity
在前台运行的 Activity 可以通过Dialog.Toast 向用户发出提示信息,而后台运行的程序,如下载.收到信息等 Service 应用,则需要使用 Notification(通知)向用户发出 ...