python笔记29-队列Queue
前言
Python的Queue模块提供一种适用于多线程编程的FIFO实现。它可用于在生产者(producer)和消费者(consumer)之间线程安全(thread-safe)地传递消息或其它数据,因此多个线程可以共用同一个Queue实例。Queue的大小(元素的个数)可用来限制内存的使用。
python2和python3的导入不一样,python2是import Queue,python3是import queue
3种Queue类型
FIFO:class Queue.Queue(maxsize=0)
FIFO即First in First Out,先进先出。Queue提供了一个基本的FIFO容器,使用方法很简单,maxsize是个整数,指明了队列中能存放的数据个数的上限。一旦达到上限,插入会导致阻塞,直到队列中的数据被消费掉。如果maxsize小于或者等于0,队列大小没有限制。LIFO:class Queue.LifoQueue(maxsize=0)
即Last in First Out,后进先出。与栈的类似,maxsize用法同上优先级队列 :class Queue.PriorityQueue(maxsize=0)
构造一个优先队列。maxsize用法同上。
常用方法:
Queue.qsize() 返回队列的大小
Queue.empty() 如果队列为空,返回True,反之False
Queue.full() 如果队列满了,返回True,反之False
Queue.full 与 maxsize 大小对应
Queue.get([block[, timeout]])获取队列,timeout等待时间
Queue.get_nowait() 相当Queue.get(False)
Queue.put(item) 写入队列,timeout等待时间
Queue.put_nowait(item) 相当Queue.put(item, False)
Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号
Queue.join() 实际上意味着等到队列为空,再执行别的操作
get和put
Queue.get是从队列里拿数据,Queue.put是往队列添加数据
import queue # 设置上限maxsize=10 q = queue.Queue(maxsize=10) # 往队列加10个数据 for i in range(100): if q.qsize() >= 10: # 存放的数据达到上限maxsize,插入会导致阻塞 break else: q.put(i) # 从队列取值 while not q.empty(): n = q.get() print("本次取出数据:%s" % n)
运行结果:
本次取出数据:0
本次取出数据:1
本次取出数据:2
本次取出数据:3
本次取出数据:4
本次取出数据:5
本次取出数据:6
本次取出数据:7
本次取出数据:8
本次取出数据:9
Queue与threading
# utf-8 import queue import threading import time exitFlag = 0 class myThread (threading.Thread): def __init__(self, threadID, name, q): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.q = q def run(self): print("Starting " + self.name) process_data(self.name, self.q) print("Exiting " + self.name) def process_data(threadName, q): while not exitFlag: queueLock.acquire() if not workQueue.empty(): data = q.get() queueLock.release() print("%s processing %s" % (threadName, data)) else: queueLock.release() time.sleep(1) users = ["user-1", "user-2", "user-3"] usernames = ["name1", "name2", "name3", "name4", "name5", "name6", "name7", "name8", "name9", "name10"] queueLock = threading.Lock() workQueue = queue.Queue(10) threads = [] threadID = 1 # 创建新线程 for tName in users: thread = myThread(threadID, tName, workQueue) thread.start() threads.append(thread) threadID += 1 # 填充队列 queueLock.acquire() for word in usernames: workQueue.put(word) queueLock.release() # 等待队列清空 while not workQueue.empty(): pass # 通知线程是时候退出 exitFlag = 1 # 等待所有线程完成 for t in threads: t.join() print("Exiting Main Thread")
运行结果:
Starting user-1
Starting user-2
Starting user-3
user-3 processing name1
user-2 processing name2
user-1 processing name3
user-3 processing name4
user-2 processing name5
user-1 processing name6
user-3 processing name7
user-2 processing name8
user-1 processing name9
user-3 processing name10
Exiting user-2
Exiting user-1
Exiting user-3
Exiting Main Thread