python-Queue(队列)(过于复杂)

简述

队列模块实现多生产者、多消费者队列。当信息必须在多个线程之间安全地交换时,它在线程编程中特别有用。此模块中的Queue类实现所有必需的锁定语义。这取决于Python中线程支持的可用性;参见线程模块。
模块实现了三种类型的队列,它们只是在检索条目的顺序上有所不同。在FIFO队列中,第一个添加的任务是第一个检索到的任务。在后进先出队列中,最近添加的条目是第一个检索到的条目(像堆栈一样操作)。使用优先级队列,条目将保持排序(使用heapq模块),并首先检索最低值的条目。
在内部,这三种类型的队列使用锁来临时阻塞竞争线程;但是,它们并不设计用于处理线程中的可重入性。
此外,模块实现了“简单”FIFO队列类型SimpleQueue,它的特定实现提供了额外的保证,以换取更小的功能。

  • class queue.Queue(maxsize=0):FIFO队列的构造函数。maxsize是一个整数,它设置可以放置在队列中的项数的上限。一旦达到此大小,插入将阻塞,直到使用队列项。如果maxsize小于或等于零,则队列大小为无穷大。

  • class queue.LifoQueue(maxsize=0):FIFO队列的构造函数。maxsize是一个整数,它设置可以放置在队列中的项数的上限。后进先出队列的构造函数。maxsize是一个整数,它设置可以放置在队列中的项数的上限。一旦达到此大小,插入将阻塞,直到使用队列项。如果maxsize小于或等于零,则队列大小为无穷大。一旦达到此大小,插入将阻塞,直到使用队列项。如果maxsize小于或等于零,则队列大小为无穷大。

  • class queue.PriorityQueue(maxsize=0): 优先级队列的构造函数。maxsize是一个整数,它设置可以放置在队列中的项数的上限。一旦达到此大小,插入将阻塞,直到使用队列项。如果maxsize小于或等于零,则队列大小为无穷大。
    首先检索值最低的条目(值最低的条目是由已排序(列表(条目))[0]返回的条目)。条目的典型模式是元组的形式:(priority_number, data)。
    如果数据元素不可比较,则可以将数据封装在一个类中,该类忽略数据项,只比较优先级编号:
    封装优先级

from dataclasses import dataclass, field
from typing import Any

@dataclass(order=True)
class PrioritizedItem:
    priority: int
    item: Any=field(compare=False)
  • class queue.SimpleQueue:一个无界FIFO队列的构造函数。简单队列缺乏高级功能,比如任务跟踪。

异常
queue.Empty
在空队列对象上调用非阻塞get()(或get_nowait())时引发异常。
queue.Full
当对已满的队列对象调用非阻塞put()(或put_nowait())时引发异常。

队列Queue

Queue, LifoQueue, 和PriorityQueue 都继承了Queue的方法。

Queue.qsize()
返回队列的大致大小。注意,qsize() > 0不保证后续get()不会阻塞,qsize() < maxsize也不保证put()不会阻塞。

Queue.empty()
如果队列为空,返回True,否则返回False。如果empty()返回True,则不能保证对put()的后续调用不会阻塞。类似地,如果empty()返回False,则不能保证对get()的后续调用不会阻塞。

Queue.full()
如果队列已满,返回True,否则返回False。如果full()返回True,则不能保证对get()的后续调用不会阻塞。类似地,如果full()返回False,则不能保证对put()的后续调用不会阻塞。

Queue.put(item, block=True, timeout=None)
把一个item放入队列. 如果选项参数 block 为 true 并且 timeout 为 None (默认值), 如果有必要阻塞它,知道有空闲磁盘. 如果 timeout 是一个正数, 它最多阻塞timeout秒,然后引发 异常如果时间到了还没有空闲空间.如果 (block 为 false), 那么将item放入队列,否则引发一个异常。

Queue.put_nowait(item)
等同于 put(item, False).

Queue.get(block=True, timeout=None)
从队列中删除一个item,然后取出。 阻塞/当取不出来。设置时间限制。

Queue.get_nowait()
等价于get(False).

Queue.task_done()
指示已完成先前排队的任务。由队列使用者线程使用。对于用于获取任务的每个get(),后续对task_done()的调用告诉队列任务上的处理已经完成。
如果join()当前处于阻塞状态,那么在处理完所有项之后,它将继续运行(这意味着对于已经放入队列()的每个项,都收到了task_done()调用)。
如果调用次数超过放置在队列中的项的次数,则引发ValueError。

Queue.join()
阻塞,直到获取和处理队列中的所有项。
每当向队列添加项时,未完成任务的数量就会增加。每当使用者线程调用task_done()来指示检索了该项并完成了对该项的所有工作时,计数就会下降。当未完成任务的计数降为零时,join()解块

如何等待进入队列的任务完成的例子:

def worker():
    while True:
        item = q.get()
        if item is None:
            break
        do_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()

SimpleQueue 对象

SimpleQueue对象提供了下面描述的公共方法。

SimpleQueue.qsize()
返回队列的大致大小。注意,qsize() > 0并不保证后续的get()不会阻塞。

SimpleQueue.empty()
如果队列为空,返回True,否则返回False。如果empty()返回False,则不能保证对get()的后续调用不会阻塞。

SimpleQueue.put(item, block=True, timeout=None)
将项放入队列。该方法从不阻塞,并且总是成功(除了潜在的低级错误,如分配内存失败)。可选的args块和超时将被忽略,只提供与Queue.put()兼容。

CPython实现细节:这个方法有一个可重入的C实现。也就是说,一个put()或get()调用可以被同一线程中的另一个put()调用中断,而不会死锁或破坏队列中的内部状态。这使得它适合于在析构函数中使用,如:_del__方法或weakref回调函数。

SimpleQueue.put_nowait(item)
等效于put(item),用于与Queue.put_nowait()兼容。

SimpleQueue.get(block=True, timeout=None)
从队列中删除并返回一个项。如果可选的args块为true, timeout为None(缺省值),则在项目可用之前,如果有必要,将阻塞。如果timeout是一个正数,那么它将阻塞最多的超时秒,如果在这段时间内没有可用的项,则引发空异常。否则(block为false),返回一个立即可用的项,否则引发空异常(在这种情况下忽略超时)。

SimpleQueue.get_nowait()
等同于get(False).

猜你喜欢

转载自blog.csdn.net/xiabenshu/article/details/88844641