本文主要是介绍Python 之队列(queue)的创建、数据进出及线程间使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
____tz_zs
队列(queue),是线程间最常用的交换数据的形式,用来在生产者和消费者线程之间的信息传递,是适用于多线程编程的先进先出的数据结构。
一、创建队列对象
1、FIFO 队列(first-in,first-out 先进先出)
class queue.Queue(maxsize=0)
maxsize:(可选参数,默认为 0)用于设定队列长度。maxsize 小于等于 0 则表示队列长度无限。 一旦队列长度达到其设定上限,插入会导致阻塞,直到队列中的数据被消费掉。
2、LIFO 队列(last-in,first-out 后进先出)
class queue.LifoQueue(maxsize=0)
maxsize:(可选参数,默认为 0)用于设定队列长度。maxsize 小于等于 0 则表示队列长度无限。 一旦队列长度达到其设定上限,插入会导致阻塞,直到队列中的数据被消费掉。
3、优先级队列
class queue.PriorityQueue(maxsize=0)
二、往队列中添加项目(Queue.put)
将一个 item 放入队列。
Queue.put(item, block=True, timeout=None)
参数:
tiem:将要放入队列中的对象。
block:可选,说明是否阻塞。
timeout:可选,指定等待时间。
- 如果可选参数 block 为 true 并且 timeout 为None(即默认值),则在队列没有空闲空间时阻塞,永远等待下去,直到有空闲空间时放入数据。
- 如果可选参数 block 为 true 并且 timeout 是正数,则在队列没有空闲空间时阻塞,它最多会阻塞 timeout 秒,如果超出了这个时间仍然没有空闲空间,则会抛出 queue.Full 异常。
- 如果可选参数 block 为 true ,则在队列有空闲空间时立即将数据放入队列中,如果没有空闲空间则立刻抛出 queue.Full 异常(在这种情况下忽略参数 timeout)。
ps:
Queue.put_nowait(item) 等同于 put(item, False)
三、从队列中取出数据(Queue.get)
从队列中移除并返回一个 item。
Queue.get(block=True, timeout=None)
参数:
block:可选,说明是否阻塞。
timeout:可选,指定等待时间。
- 如果可选参数 block 为 true 并且 timeout 为None(即默认值),则在队列中没有数据时阻塞,永远等待下去,直到队列中有数据可以获取。
- 如果可选参数 block 为 true 并且 timeout 是正数,则在队列中没有数据时阻塞,它最多会阻塞 timeout 秒,如果超出了这个时间而队列中仍然没有数据,则会抛出 queue.Empty 异常。
- 如果可选参数 block 为 true ,则在队列有数据时立即取出,如果没有数据则立刻抛出 queue.Empty 异常(在这种情况下忽略参数 timeout)。
ps:
Queue.get_nowait() 相当于 get(False) 。
四、Queue.join() 和 Queue.task_done() 的使用
- 每当有 item 被 put 到队列时,未完成任务的计数(Queue 对象 的 unfinished_tasks 属性)就会加 1。
- 每当调用 task_done()方法时,计数就会减 1。当未完成任务的数量降至 0 时,Queue.join()的阻塞消失。
例1:队列中存储了三个 item,在线程结束时队列随之消失。
# -*- coding:utf-8 -*-
"""
@author: tz_zs
"""import queueq = queue.Queue()
print("队列大小:%s" % q.qsize()) # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks) # 未完成的任务数q.put(222)
q.put(333)
q.put(444)print("队列大小:%s" % q.qsize()) # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks) # 未完成的任务数print("结束")"""
队列大小:0
未完成的任务数:0
队列大小:3
未完成的任务数:3
结束Process finished with exit code 0
"""
例2:队列中存入三个 item,未完成任务的计数为3,未处理完,所以进程阻塞在 Queue.join() 处。
# -*- coding:utf-8 -*-
"""
@author: tz_zs
"""import queueq = queue.Queue()
print("队列大小:%s" % q.qsize()) # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks) # 未完成的任务数q.put(222)
q.put(333)
q.put(444)print("队列大小:%s" % q.qsize()) # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks) # 未完成的任务数q.join()
print("结束")"""
队列大小:0
未完成的任务数:0
队列大小:3
未完成的任务数:3
"""
例3:队列中存入三个 item,未完成任务的计数为3。虽然已通过 Queue.get() 取出,但计数并没有减少,进程仍阻塞在 Queue.join() 处。
# -*- coding:utf-8 -*-
# -*- coding:utf-8 -*-
"""
@author: tz_zs
"""import queueq = queue.Queue()
print("队列大小:%s" % q.qsize()) # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks) # 未完成的任务数q.put(222)
q.put(333)
q.put(444)
q.get()
q.get()
q.get()print("队列大小:%s" % q.qsize()) # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks) # 未完成的任务数q.join()
print("结束")"""
队列大小:0
未完成的任务数:0
队列大小:0
未完成的任务数:3
"""
例4:队列中存入三个 item,未完成任务的计数为3。通过调用 Queue.task_done() 将计数减少到 0,线程未阻塞。
# -*- coding:utf-8 -*-
"""
@author: tz_zs
"""import queueq = queue.Queue()
print("队列大小:%s" % q.qsize()) # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks) # 未完成的任务数q.put(222)
q.put(333)
q.put(444)
q.task_done()
q.task_done()
q.task_done()print("队列大小:%s" % q.qsize()) # 队列大小
print("未完成的任务数:%s" % q.unfinished_tasks) # 未完成的任务数q.join()
print("结束")"""
队列大小:0
未完成的任务数:0
队列大小:3
未完成的任务数:0
结束Process finished with exit code 0
"""
五、队列大小的相关属性和方法
1、Queue.qsize()
返回队列的大致大小。注意,qsize() > 0 不保证后续的 get() 方法不被阻塞,qsize() < maxsize 也不保证 put() 方法不被阻塞。
2、Queue.empty()
如果队列为空,返回 True ,否则返回 False 。如果 empty() 返回 True ,不保证后续调用的 put() 不被阻塞。类似的,如果 empty() 返回 False ,也不保证后续调用的 get() 不被阻塞。
3、Queue.full()
如果队列是满的返回 True ,否则返回 False 。如果 full() 返回 True 不保证后续调用的 get() 不被阻塞。类似的,如果 full() 返回 False 也不保证后续调用的 put() 不被阻塞。
4、Queue.maxsize
属性,创建队列时传入参数,代表队列的最大容量,小于等于 0 代表无线。
5、Queue.queue
# -*- coding:utf-8 -*-
"""
@author: tz_zs
"""import queueq = queue.Queue()q.put(222)
q.put(333)
q.put(444)
dq = q.queue # deque([222, 333, 444])
print(dq)
l = list(dq) # <class 'list'>: [222, 333, 444]
print(l)
"""
deque([222, 333, 444])
[222, 333, 444]
"""
六、官网例子:如何等待排队的任务被完成的示例
def worker():while True:item = q.get()if item is None:breakdo_work(item)q.task_done()q = queue.Queue()
threads = []
for i in range(num_worker_threads):t = threading.Thread(target=worker)t.start()threads.append(t)for item in source():q.put(item)# block until all tasks are done
q.join()# stop workers
for i in range(num_worker_threads):q.put(None)
for t in threads:t.join()
这篇关于Python 之队列(queue)的创建、数据进出及线程间使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!