queue 队列源码分析
2024-01-25 14:31:35
Python 进阶:queue 队列源码分析
queue 模块提供适用于多线程编程的先进先出(FIFO)数据结构。因为它是线程安全的,所以多个线程很轻松地使用同一个实例。
源码分析
先从初始化的函数来看:
def __init__(self, maxsize=0):
"""Initialize a queue object with a maximum size."""
if maxsize <= 0:
maxsize = sys.maxsize
self.maxsize = maxsize
self.mutex = Lock()
self.not_empty = Condition(self.mutex)
self.not_full = Condition(self.mutex)
self.queue = []
从这初始化函数能得到哪些信息呢?首先,它接受一个参数 maxsize
,表示队列的最大尺寸。如果 maxsize
小于或等于0,它将被设置为 sys.maxsize
,表示队列没有大小限制。然后,它创建了三个锁:一个互斥锁 mutex
,两个条件变量 not_empty
和 not_full
。互斥锁用于保护队列,确保每次只有一个线程可以访问队列。条件变量用于通知线程队列是否为空或已满。最后,它创建了一个空列表 queue
来存储队列中的项。
接下来,我们来看一下 put()
方法:
def put(self, item, block=True, timeout=None):
"""Put an item into the queue."""
with self.mutex:
while self.full() and block:
self.not_full.wait(timeout)
if self.full():
raise QueueFull
self.queue.append(item)
self.not_empty.notify()
put()
方法将项放入队列中。它首先获取互斥锁 mutex
,然后检查队列是否已满。如果队列已满,它将等待直到队列变为空或超时。如果队列已满并且 block
为 False
,它将引发 QueueFull
异常。如果队列不 full,它将项添加到队列中,然后通知条件变量 not_empty
,表示队列已不再为空。
最后,我们来看一下 get()
方法:
def get(self, block=True, timeout=None):
"""Remove and return an item from the queue."""
with self.mutex:
while self.empty() and block:
self.not_empty.wait(timeout)
if self.empty():
raise QueueEmpty
item = self.queue.pop(0)
self.not_full.notify()
return item
get()
方法从队列中移除并返回一个项。它首先获取互斥锁 mutex
,然后检查队列是否为空。如果队列为空,它将等待直到队列变为非空或超时。如果队列为空并且 block
为 False
,它将引发 QueueEmpty
异常。如果队列不为空,它将从队列中移除并返回第一个项,然后通知条件变量 not_full
,表示队列已不再为满。
以上是对 Python queue 模块源码的简要分析。希望本文能帮助读者对 queue 模块有更深入的理解和掌握。