为什么Python的queue.get()函数要检查获取not_empty锁的with块内队列是否不为空?
我试图更好地理解队列库,所以这里的代码让我摸不着头脑:
def get(self, block=True, timeout=None):
'''Remove and return an item from the queue.
If optional args 'block' is true and 'timeout' is None (the default),
block if necessary until an item is available. If 'timeout' is
a non-negative number, it blocks at most 'timeout' seconds and raises
the Empty exception if no item was available within that time.
Otherwise ('block' is false), return an item if one is immediately
available, else raise the Empty exception ('timeout' is ignored
in that case).
'''
with self.not_empty: # <-------- notice this lock guarantees the queue is not empty
if not block:
if not self._qsize():
raise Empty
elif timeout is None:
while not self._qsize(): # <---------- so then why is this necessary?
self.not_empty.wait()
elif timeout < 0:
raise ValueError("'timeout' must be a non-negative number")
else:
endtime = time() + timeout
while not self._qsize():
remaining = endtime - time()
if remaining <= 0.0:
raise Empty
self.not_empty.wait(remaining)
item = self._get()
self.not_full.notify()
return item
根据上面的注释,我想知道为什么有必要检查队列是否不为空,如果我们已经获取了保证队列不为空的锁?我对“with”语句的理解是,它在锁 self.not_empty 上调用 .acquire() ,并且 .acquire() 会阻塞,直到锁可用。那么超时不应该在那里处理吗?
I'm trying to better understand the queue library, so here's the code that's making me scratch my head:
def get(self, block=True, timeout=None):
'''Remove and return an item from the queue.
If optional args 'block' is true and 'timeout' is None (the default),
block if necessary until an item is available. If 'timeout' is
a non-negative number, it blocks at most 'timeout' seconds and raises
the Empty exception if no item was available within that time.
Otherwise ('block' is false), return an item if one is immediately
available, else raise the Empty exception ('timeout' is ignored
in that case).
'''
with self.not_empty: # <-------- notice this lock guarantees the queue is not empty
if not block:
if not self._qsize():
raise Empty
elif timeout is None:
while not self._qsize(): # <---------- so then why is this necessary?
self.not_empty.wait()
elif timeout < 0:
raise ValueError("'timeout' must be a non-negative number")
else:
endtime = time() + timeout
while not self._qsize():
remaining = endtime - time()
if remaining <= 0.0:
raise Empty
self.not_empty.wait(remaining)
item = self._get()
self.not_full.notify()
return item
As per my annotations above, I'm wondering why it's necessary to check if the queue is not empty, if we've already acquired the lock guaranteeing the queue is not empty? My understanding of the "with" statement is that it calls .acquire() on the lock self.not_empty, and .acquire() blocks until the lock is available. So shouldn't timeouts be handled there?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论